Angular HTTP GET - json

I have a server running on "localhost:3000". It displays data as JSON at e.g. "localhost:300/locations".
My "data.service.ts" includes this code:
path: string = 'http://localhost:3000'
constructor(private http: HttpClient) { }
// Locations
getAllLocations(): Observable<Location[]> {
let location = null;
this.http.get(this.path + '/locations')
.map((res => location = res))
.catch((error: any) => Observable.throw(console.log(error)));
return location;
}
In my result.component.ts I'm running this code:
constuctor(private dataservice: DataService) { }
ngOnInit() {
console.info(this.dataservice.getAllLocations());
}
I'm expecting to get as output all Locations as JSON, instead of this the output is "null".
Does anyone have a suggestion on how to make this work properly?
UPDATE:
Also tried this for the HTTP call:
getAllLocations(): Observable<Location[]> {
this.http.get<Location[]>(this.path + '/locations')
.pipe(
tap(items => console.info('fetched items'))
);
}
The output for this code is unfortunately: "Object { _isScalar: false, source: {...}, operator: {...} }"

Did you know that HttpClient#get returns an Observable? You can just return the get method in your method.
Secondly, you can set an interface to the method so that it'll return the JSON as typed.
Lastly, you can use template literals in your API URL.
/**
* Retrieves a list of locations.
* (TODO: Add better documentation here)
*/
getAllLocations(): Observable<Location[]> {
return this.http.get<Location[]>(`${this.path}/locations`);
}
You can then handle this in the actual component that calls this method:
constuctor(private dataservice: DataService) { }
ngOnInit() {
this.dataservice.getAllLocations().subscribe(result => {
console.log(result);
});
}

You have to return Observable from the service:
path: string = 'http://localhost:3000'
constructor(private http: HttpClient) { }
// Locations
getAllLocations(): Observable<Locations[]> {
return this.http.get(this.path + '/locations').pipe(
map((res => location = res)),
catch((error: any) => Observable.throw(console.log(error))));
}
And subscribe to it in the component.
constructor(private dataservice: DataService) { }
ngOnInit() {
this.dataservice.getAllLocations().subscribe(result => {
console.log(result);
})
}

Related

Get titles from Wikipedia

I am kinda new to Angular.
I am trying to get 4 titles from Wikipedia API, but i can't figure up what's wrong in my code
this is the eample URL for 1 title
example URL = https://en.wikipedia.org/w/api.php?action=query&prop=pageprops&format=json&titles=Wilson_Lumpkin
model
IwikiItem.ts:
export interface IWikiItem {
batchcomplete?: string;
query?: Query;
}
export interface Query {
normalized?: Normalized[];
pages?: Pages;
}
export interface Normalized {
from?: string;
to?: string;
}
export interface Pages {
id?: The4101295;
}
export interface The4101295 {
pageid?: number;
ns?: number;
title?: string;
pageprops?: Pageprops;
}
export interface Pageprops {
defaultsort?: string;
page_image_free?: string;
wikibase_item?: string;
}
Component
private titles = [
'Wilson_Lumpkin',
'Robert Toombs',
'Saxby Chambliss',
'Wyche Fowler',
];
export class HomeComponent implements OnInit {
dataSource: MatTableDataSource<IWikiItem>;
constructor(private srv: SrvService) {
this.titles.forEach((name) => {
this.srv
.getWiki('action=query&prop=pageprops&format=json&titles=' + name)
.subscribe((data) => {
console.log(data.query),
(this.dataSource: new MatTableDataSource<IWikiItem[data]>);
(err) => {
console.log(err);
};
});
});
}
}
service
export class SrvService {
readonly base_url = 'https://en.wikipedia.org/w/api.php?';
getWiki(title: string) {
return this.http.get<IWikiItem>(this.base_url + title);
}
constructor(private http: HttpClient) {}
}
What's wrong here? i am, getting this error in console:
error msg
Edit 1
I am getting an error this.handle eror.
error
I guess Wikipedia APis does not support CORS. So instead of normal http request, you need t make a jsonp request.
For jsonp request you need to import module HttpClientJsonpModule in your application.
After that you can make the request like below.
Reference Link
getWiki(title: string) {
const url = this.base_url + title;
return this.http.jsonp(url, 'callback').pipe(
catchError(this.handleError) // then handle the error
);
}
callback(response) {
console.log("response", response);
}
handleError(error){
console.log(error);
}
Working sample Link

Facing issues on accessing json() in angular, HttpClient. Looking for alternatives

I would like to get all the posts from 'https://jsonplaceholder.typicode.com/posts'.
However the update of Http to HttpClient, not allowing to access "json()" (at response.json()).
Please guide for a solution.
Regards.
export class PostsComponent {
posts: any[];
constroctur(http: HttpClient) {
http
.get('https://jsonplaceholder.typicode.com/posts')
.subscribe((response) => {
this.posts = response.json();
});
}
}
The best way is the pass the data type to the response argument "response : any[]".
export class PostsComponent {
posts: any[];
constroctur(http: HttpClient) {
http
.get('https://jsonplaceholder.typicode.com/posts')
.subscribe((response : any[]) => {
this.posts = response;
});
}
}
You must set the content type along with the request. It should look like below.
const headers = { 'Content-Type': 'application/json'};
export class PostsComponent {
posts: any[];
constroctur(http: HttpClient) {
http
.get('https://jsonplaceholder.typicode.com/posts',{headers})
.subscribe((response : any[]) => {
this.posts = response;
});
}
}
http
.get('https://jsonplaceholder.typicode.com/posts')
.subscribe((response) => {
this.posts = response;
});
All you need to do, and arguably the best choice is setting the posts to the response. It's already a JavaScript object.
If, for whatever reason you require a JSON string, then you can look into JSON.Stringify:
this.posts = JSON.stringify(response)

Angular can't read value of 'undefined' - unable to read value of 'casestudy' in the setTitle() method?

This is my component:
export class CaseStudyDetailComponent implements OnInit {
casestudy: CaseStudy;
constructor ( private caseStudyService: CaseStudyService, private route: ActivatedRoute, public titleService: Title ) { }
ngOnInit() {
this.route.params.subscribe((params: { Handle: string }) => {
this.caseStudyService.getCaseStudy(params.Handle).subscribe(casestudy => this.casestudy = casestudy);
});
this.titleService.setTitle(this.casestudy.Handle);
}
}
This is the service it is calling:
getCaseStudy(Handle: string): Observable<CaseStudy> {
return this.http.get<CaseStudy>(`${environment.apiPath}/project/handle/${Handle}`);
}
I want to be able to access the value of 'casestudy' in the 'setTitle()' method. I might potentially just be misunderstanding expected behaviour or have my syntax wrong.
Let me know if more information is required.
Because your console.log gets excecuted before your subscribe can set the response in the caseStudy.
To fix this put the console.log method in the subscribe
this.caseStudyService.getCaseStudy().subscribe(caseStudy => {
... code
console.log(caseStudy);
});

How can I save http get response object in angular 6

I'm new to angular and i'm trying to figure out how can I save in a local variable the response of http.get(url)
Here is my code :
export class AppComponent {
private url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&api_key=MY_KEY&format=json&artist=The+Weeknd' ;
public data;
constructor(private http: HttpClient) {
this.http.get(this.url).subscribe(response => this.data = response);
console.log(this.data); // -> The result is undefined...
}
}
At first, I tried this.http.get(this.url).subscribe(response => console.log(response)); and that was working has expected, however an assignation doesn't work.
Thanks a lot !
You're code is exactly correct. The reason the console.log is not showing the response value is because it is running BEFORE the response is processed. Once the HTTP request has been started, JavaScript continues executing the current function.
If you want to log the response, you need to do so inside the response handler
export class AppComponent {
private url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&api_key=MY_KEY&format=json&artist=The+Weeknd' ;
public data;
constructor(private http: HttpClient) {
this.http.get(this.url).subscribe(response => {
this.data = response;
console.log(this.data);
});
}
}
You are doing async HTTP call. so you need to add console.log inside subscribe.
export class AppComponent {
private url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&api_key=MY_KEY&format=json&artist=The+Weeknd' ;
public data;
constructor(private http: HttpClient) {
this.http.get(this.url).subscribe(response => {
this.data = response;
console.log(this.data);
});
}

Read data from a local JSON file with data binding in ngOnInit() results in undefined variable

I am trying to get a data from json file in the assets folder, and then assign this data to a variable that will be binded to another #Input variable of a child componenet.
Code
Based on multiple solutions on the net, I retrieve my JSON data this way:
#Injectable()
export class JSONService {
constructor(private http: HttpClient) { }
public fromJSON(jsonFileName: string): Observable<any[]> {
let result: any[] = new Array();
let pathToJson: string = "assets/" + jsonFileName + ".json";
return this.http.get(pathToJson).map(data => {
let result: any[] = new Array();
// Apply some treatment on data and push it to the result array
return result;
});
}
}
I then call my service in the ngOnInit() method of the parent component:
ngOnInit() {
this.jsonService.fromJSON("users.json").subscribe(fields => {
this.fields= fields;
console.log(this.fields); // Log (I): this.fields is well defined
});
console.log(this.fields); // Log (II): this.fields is undefined
}
Where the variable fields is binded to a child component:
<child-component [childFields] = "fields"></child-component>
Problem
The problem that I am facing is that the asynchronous call to the fromJSON method causes this.fields to be undefined at some point of the lifecycle of the page execution (Log (II) from the code above), and this causes to send an undefined value of the this.fields variable to the child component.
How to avoid to have an undefined value of the fields variable, and make sure that the child component is always loaded with the data from the json file?
Just add *ngIf to check if the data is loaded
<child-component *ngIf="fields" [childFields] = "fields"></child-component>
Service.ts
#Injectable()
export class JSONService {
constructor(private http: HttpClient) { }
public fromJSON(jsonFileName): Observable<any[]> {
console.warn('Retriving Default Data from File.......');
return this.http.get(filename)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || [];
}
private handleError(error: any) {
const errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
console.log('Server Error!');
return Observable.throw(errMsg);
}
}
parent.component.ts
constructor(public jsonService: jsonService) {
}
ngOnInit() {
this.jsonService.fromJSON('assets/users.json').subscribe(
function (success) {
this.data = success;
this.datahandle(success);
},
error => console.log('Getting Server Data Error :: ' +
JSON.stringify(error)));
}
datahandle(jsonData){
console.log('check data' + JSON.stringify(jsonData)); <-----check data
// may parse your jsonData if required
this.fields = jsonData ;
let keys = Object.keys(jsonData);
console.log(keys);
}
}
parent.component.html
<child-component *ngIf="fields" [childFields] = "fields"></child-component>
Assuming your component is somewhat like below
export class SomeComponent implements OnInit {
public fields: any[];
ngOnInit() {
this.jsonService.fromJSON("users.json").subscribe(fields => {
this.fields = fields;
console.log(this.fields); // Log (I): this.fields is well defined
});
console.log(this.fields); // Log (II): this.fields is undefined
}
}
Then you can either initialize fields with an empty array
public fields: any[] = [];
OR in template
<child-component *ngIf="fields" [childFields]="fields"></child-component>