I'm building a school project using angular js and node js as a backend, I'm trying to display the event in my front-end using Angular JS from EventBrite, After spending a few hours checking different tutorial I wrote this code
Node JS code:
router.get('/', (req, res)=>{
axios.get(`${EventsBriteAPI}`).then(result=>{
let relevantData = result.data.data.events
res.status(200).json(relevantData);
console.log(results );
})
.catch(error => {
res.status(500).send(error);
})
});
My service code:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class EventsService {
uri = 'http://localhost:4600/events';
constructor(private httpClient: HttpClient) {}
getAllEvents(){
return this.httpClient.get(this.uri);
}
}
My component code
import { Component } from '#angular/core';
import { EventsService } from './events.service';
import { Observable } from 'rxjs/internal/Observable';
#Component({
selector: 'events',
templateUrl: 'events.Component.html'
})
export class EventsComponent {
title = "List of events";
eventObservable : Observable<any[]> ;
constructor(service: EventsService){
this.eventObservable = service.getAllEvents();
console.log(this.eventObservable);
}
}
When I'm running my code I'm getting this error
src/app/component/events/events.component.ts(21,5): error TS2322: Type 'Observable' is not assignable to type 'Observable'.
The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
Type 'Object' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more. and It's not displaying anything in my front-end
Could you please help me with that.
we don't need to use Observable type variable unless you are using async pipe or for any specific requirement.
You can do some like below,
EventsComponent.ts
eventObservable: any = [];
constructor(private service: EventsService) {
this.service.getAllEvents().subscribe((response: any) =>{
this.eventObservable = response;
console.log(this.eventObservable);
});
}
we generally use ngOnInit() for calling an api data not in the constructor().
Related
I'm creating an Angular application connected to a Nodejs backend server. The Nodejs server response can be an array or Json object. I have to catch the correct data type according to the server response.
This is my Angular service code.
Note that my HttpClient functions return Json objects. Is there any function that returns any type of data?
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { map } from 'rxjs/operators'
import { City } from '../models/City';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class CityService {
constructor(private http: HttpClient) { }
API_URI = 'http://localhost:5000'
getCities() {
return this.http.get(`${this.API_URI}/City`);
}
getCity(id: string) {
return this.http.get(`${this.API_URI}/City/${id}`);
}
deleteCity(id: string) {
return this.http.delete(`${this.API_URI}/City/${id}`);
}
saveCity(city: City) {
return this.http.post(`${this.API_URI}/City`, city);
}
updateCity(id: string|number|undefined, updatedCity: City): Observable<City> {
return this.http.put(`${this.API_URI}/City/${id}`, updatedCity);
}
}
Thanks a lot !
Check the returned type and transform the response in a map operator, you can then handle it accordingly in your subscribe
getCities() {
return this.http.get(`${this.API_URI}/City`).pipe(
map( body => {
return {
isArray: Array.isArray(body),
data: body
}
})
)
}
It's strange behavior for an API to return either an array or object (usually it's always one or the other). I suspect there may be something missing in your understanding/processing of the response, but I could be wrong😊
I am having some issues serving my app using ssr. It works fine when it loads normally using ng s --o. But when I serve it with npm run dev:ssr and load the path it sometimes takes extremely long to serve while using the resolver below. Enough to timeout when deployed (>60s). I am using node 10.
solution.resolver.ts
import { Injectable } from '#angular/core';
import { AngularFirestore } from '#angular/fire/firestore';
import {
Resolve,
RouterStateSnapshot,
ActivatedRouteSnapshot
} from '#angular/router';
import { from, Observable } from 'rxjs';
import { map, mergeMap, reduce } from 'rxjs/operators';
import { Solution } from './Solution.type';
import { AngularFireStorage } from '#angular/fire/storage';
#Injectable({
providedIn: 'root'
})
export class SolutionResolver implements Resolve<Solution[]> {
constructor(
private firestore: AngularFirestore,
private storage: AngularFireStorage
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<any> { // Solution[]
return this.firestore.collection('solutions').get() // Observable<doc>
.pipe(
map( snapshot => snapshot.docs.map( doc => doc.data() ) as Solution[]), // Observable<Solution[]>
mergeMap( solutions => from(solutions) ), // stream of Observable<Solution>
mergeMap( solution => {
return this.storage.ref( solution.image ).getDownloadURL()
.pipe( map( url => ({...solution, image: url}) ))
}), // stream of <Observable<Solution>
reduce( (acc: Solution[], value ) => {acc.push(value); return acc; }, []) // <Observable<Solution[]>
)
}
}
The issue may be related to this.storage.ref( solution.image ).getDownloadURL(). There are no error messages in the console. To make it even worse sometimes it does work as expected.
I previously had the same issue using the getDownloadURL pipe from angularfire: https://github.com/angular/angularfire/blob/master/docs/storage/storage.md#downloading-files
Any idea what is going wrong?
update: It's probably related to this issue: https://github.com/angular/angularfire/issues/2725
I am trying to pass data to a ReactJS component using NodeJS by making a simple NodeJS API hosted in a separate localhost (:9000). But I'm getting an error.
TypeError: this is undefined
My belief is that this error occurred due to using 'this' inside the functional component. But I cannot find a way to resolve this problem.
The code which has the error:
import React from 'react';
import ReactDOM from 'react-dom';
class News extends React.Component{
constructor (props){
super(props);
this.state={apiResponse:""};
}
callAPI(){
fetch("http://localhost:9000/testAPI")
.then(res => res.text ())
.then(res => this.setState({apiResponse: res}));
}
componentWillMount(){
this.callAPI();
}
}
function Newsexport() {
return (
<div class="container1">
<h1>IT WORKS YO!</h1>
<p>{this.state.apiResponse}</p>
</div>
)
};
export default Newsexport;
The code of the simple API hosted with NodeJS (/api/routes/testAPI.js)
var express = require("express");
var router=express.Router();
router.get("/", function(req,res,next){
res.send("API is working");
});
module.exports=router;
You are using this in a functional component which is wrong. Also you are setting state in one component and expecting the value in another component. Instead combine the two components like below -
class News extends React.Component{
constructor (props){
super(props);
this.state={apiResponse:""};
}
callAPI = () => {
fetch("http://localhost:9000/testAPI")
.then(res => res.text ())
.then(res => this.setState({apiResponse: res}));
}
componentWillMount(){
this.callAPI();
}
render() {
return (
<div class="container1">
<h1>IT WORKS YO!</h1>
<p>{this.state.apiResponse}</p>
</div>
)
}
}
export default News;
Let me know if this helps.
This question already has answers here:
How do I return the response from an Observable/http/async call in angular?
(10 answers)
Closed 5 years ago.
I am newbie to MEAN stack development. So, please help me to figure out the problem.
app.js
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static(path.join(__dirname, './darwin-src/public')));
const port = 3000;
app.get('/images', (req, res) => {
console.log('In server');
var data;
var Scraper = require ('images-scraper')
, google = new Scraper.Google();
google.list({
keyword: 'banana',
num: 10,
detail: true,
nightmare: {
show: false
}
})
.then(function (data) {
console.log('first 10 results from google', data);
res.end("" + data);
})
.catch(function(err) {
console.log('err', err);
});
});
app.listen(port, () => {
console.log(`Starting the server at port ${port}`);
});
image-service.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import { Image } from './model/image';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/observable/of';
#Injectable()
export class ImageServiceService {
constructor(private http: Http) { }
private serverApi = 'http://localhost:3000';
public getImages(image: string): Observable<Image[]> {
console.log('Inside Service');
let URI = `${this.serverApi}/images`;
return this.http.get(URI)
.map(function(res) {
return res.json();
});
}
}
image-view.component.ts
import { Component, OnInit } from '#angular/core';
import { ImageServiceService } from '../image-service.service';
import { Image } from '../model/image';
#Component({
selector: 'app-image-view',
templateUrl: './image-view.component.html',
styleUrls: ['./image-view.component.css']
})
export class ImageViewComponent implements OnInit {
private data: Image[] = [];
constructor(private imageService: ImageServiceService) { }
ngOnInit() {
}
onSubmit(image: string) {
console.log(image);
this.imageService.getImages(image).subscribe(response => this.data = response);
console.log(this.data.length);
}
}
The length of array is zero and I can't figure out why. The response comes on nodejs console after a while but the frontend displays the result before the response comes. Please help!
Hit the server url separately in browser and see if you get the expected response. If this is okay, then the problem is with the client.
On seeing your client code, one issue seems obvious. You are not using the observable from ImageServiceService properly. All your manipulations should be within the subscribe method.
onSubmit(image: string) {
this.imageService.getImages(image).subscribe(response => {
this.data = response;
console.log(this.data.length);
// Do other manipulations that you wish to do
});
}
If you using the observable to display something in the view, then
consider . using async pipe
The code in the subscribe handler is not executed synchronously. So, your console.log statement is executed before you get a response from your server. I don't see your image-view.component.html markup. But, I believe you need to use the async pipe in your bound option.
private data$: Observable<Image[]>;
onSubmit(image: string) {
console.log(image);
this.data$ = this.imageService.getImages(image);
}
And you HTML:
<div *ngFor="let image of data$ | async">
{{image.value}}
</div>
I have node api that returns data to browser using this api :
app.get('/api/patients',function(req,res){
Patient.getPatients(function(err,patients){
if(err){
throw err;
}
console.log(patients.length);
res.json(patients);
});
});
I am trying to call this api from the service class.
import { Injectable } from '#angular/core';
import { Patient } from '../patient.interface';
#Injectable()
export class PatientDataService {
patients : Patient[] =[];
constructor() { }
getAllPatients(): Patient[]
{
// What to do here ??
}
}
How do i return data from node api to service ?
Use this
#Injectable()
export class PatientDataService {
patients : Patient[] =[];
constructor(private http:Http) { }
getAllPatients()
{
return this.http.get('base_url/api/people').map((res)=>res.json());
}
}
and in your component inject this service and call
this.patientService.getAllPatients().subscribe((data)=>{
//data is your patient list
})
You can first import the Angular2 Http library into your service:
import { Http } from '#angular/http';
I also import rx/js for use of Observables and mapping.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
You can then inject the library into your service:
constructor(private _http: Http) { }
Make your http call to your node.js server like this:
getAllPatients(): Patient[]
{
// What to do here ??
return this._http.get('/api/patients')
.map(this.extractData)
.catch(this.handleError);
}
For more information, documentation, and clarification please read the Angular 2 Http Docs