Call json file from url - json

I'm trying to call json file from url and get data. But no error and nothing working. I don't have any idea how to solve it.
service
export class JsonService {
public getMenuData(): Observable<any> {
return new Observable((observer) => {
this.http.get('https://demored.ddns.net:50443/demored/path_image/menu.json').subscribe((response)=> {
observer.next(response);
observer.complete();
});
});
}
Component
ngOnInit() {
this.getJson();
}
getJson(){
this.jsonService.getMenuData().toPromise().then(data => {
this.menuJson = data;
console.log("Menu from json file ",this.menuJson);
}).catch((err) => {
console.log('error in fetching data',err);
});
}

You make the GET request on the service, where you convert the request into a promise with toPromise(). From there in any component you can call the method for the service declared in the constructor this.serviceJson() and resolve the promise with a .then () or .catch ()
export class JsonService {
getMenuData(): Promise<any> {
return this.http.get<any>('https://demored.ddns.net:50443/demored/path_image/menu.json').toPromise()
}
component
ngOnInit() {
this.getJson();
}
async getJson(){
await this.jsonService.getMenuData().then(data => {
this.menuJson = data;
console.log("Menu from json file ",this.menuJson);
}).catch((err) => {
console.log('error in fetching data',err);
});
}

Related

How to fetch JSON results from multiple APIs using redux

I have three different APIs that I am fetching JSON results from and I want to dispatch all three of them using React Native Redux. I am trying to implement a server side search filter that gets the response from all three APIs. How can I do this?
actions.ts
// API 1
export const getCountries = () => {
try {
return async (dispatch) => {
const response = await axios.get(`${BASE_URL}`);
if (response.data) {
dispatch({
type: GET_COUNTRIES,
payload: response.data,
});
} else {
console.log("Unable to fetch data from the API BASE URL!");
}
};
} catch (error) {
console.log(error);
}
};
// API 2
export const getStates = () => {
try {
return async (dispatch) => {
const response = await axios.get(`${BASE_URL_STATES}`);
if (response.data) {
dispatch({
type: GET_STATES,
payload: response.data,
});
} else {
console.log("Unable to fetch data from the API BASE URL!");
}
};
} catch (error) {
console.log(error);
}
};
// API 3
export const getCounties = () => {
try {
return async (dispatch) => {
const response = await axios.get(`${BASE_URL_COUNTIES}`);
if (response.data) {
dispatch({
type: GET_COUNTIES,
payload: response.data,
});
} else {
console.log("Unable to fetch data from the API BASE URL!");
}
};
} catch (error) {
console.log(error);
}
};

Angular 2 this.data is undefined

I'm trying to read the content of my JSON file through my "GetJsonService".
app.component.ts:
data: any;
constructor(private jsonService: GetJsonService) {}
ngOnInit() {
this.getRecords();
console.log(this.data);
}
getRecords() {
this.jsonService.getRecords().subscribe(data => {
this.data = data;
}, err => {
console.log(err);
});
}
get-json.service.ts
constructor(private http: Http) { }
data: any;
getRecords() {
return this.http.get('assets/standorte.json').map(data => {
this.data = data.json();
return data.json();
}, err => {
if (err) {
return err.json();
}
});
}
I want to put the content of data.json() into this.data to use it.
But when I log this.data it is "undefined".
I'm completely new to Angular 2 and Typescript, so I really would be thankful when someone helps me.
Greetings
#MauricioSipmann solved my problem.
The problem was that the code runs asynchronously in a request.
I actually knew that but Typescript confused me a little bit.
Thank you to all responders!
Just modify your method getRecords()
Use it as below :
getRecords() {
this.jsonService.getRecords().subscribe(data => {
this.data = data;
console.log(this.data);
}, err => {
console.log(err);
});
}
Instead of logging after calling method you should do inside success of service.
This is common issue which every developer face at initiate stage of Angular 2+.
It is an async call. So the issue is you console.log() statement is executing before your service assign value this.data = data; to the variable.
With your code if you display data in HTML it will probably work fine. Just it will not log properly where you got confused.
If you are using angular 6, no need to convert to json. Just return the request.
getRecords() {
return this.http.get('assets/standorte.json')
}
another problem is your not re throw the async state ..try this:
ngOnInit() {
this.getRecords().then((resp)=>{
console.log(resp);
});
}
getRecords() {
return new Promise<>((resolve,reject)
=> {
this.jsonService.getRecords().subscribe(data => {
this.data = data;
resolve(data);
}, err => {
console.log(err);
reject(err);
});
})
}

Angular 2:Not able to get a token in another component which is stored in local storege

I have one application which include login and home component,
login.service.ts
let body = JSON.stringify(data);
console.log("logged in user",body);
return this._http.post('http://localhost:8080/api/user/authenticate', body, { headers: contentHeaders })
.map(res => res.json())
.map((res) => {
var token1:any = res;
console.log(token1);
if (token1.success) {
localStorage.setItem('auth_token', token1.token);
this.LoggedIn = true;
}
return res.success;
});
}
isLoggedIn() {
return this.LoggedIn;
}
in this service i am getting token in variable token1 and isLogged method contain
constructor(private _http: Http) {
this.LoggedIn = !!localStorage.getItem('auth_token'); }
Login.component.ts
login(event, username, password)
{
this.loginService.login(username, password)
.subscribe(
response => {
this.router.navigate(['/home']);
alert("login successfull");
},
error => {
alert(error.text());
console.log(error.text());
}
);
From this login i can able to authenticate and and its routing to home component,
Home.serice.ts
getClientList()
{
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let authToken = localStorage.getItem('auth_token');
headers.append('X-auth-Token', 'authToken')
return this._http.get('http://localhost:8080/api/v1/client/list?isClient=Y', {headers})
.map(res => res.json())
}
Home.component.ts
onTestGet()
{
this._httpService.getClientList()
.subscribe(
data => this.getData = JSON.stringify(data),
error => alert(error),
() => console.log("finished")
);
}
now question is how can i access that token in home component which is in token1 varible(login) i have tired to getitem token.but i am getting token null.please anybody help me.
thanks in advance
localStorage.getItem('auth_token')
This should work, but you are getting null, because lifecycle of the data different.
I suggest you to use Subject construction for this purpose, especially you already have service with data.
Example:
loginInfo$ = new Subject();
private _logininfo = null;
getLoginData () {
if(!_logininfo) {
this.http..... { this._loginInfo = data;
this.loginInfo$.next(data); }
return this.loginInfo$.first()
}
else return Observable.of(this._logininfo);
}
So now, your service at the same time storage of data and handler for missing login.

accessing object attributes in the react render method

I have written a small react component which fetches some data from the open weather api. The fetch succeeds and I can get a json object in the response.
I then save this response to the components state using this.setState({})
And the react dev tools show the forecast object is infact saved in state.
However when I come to rendering any of the data i always get an error stating `cannot read property 'forecast' of null.
Below is the react component and a screen shot of the object itself.
export default class Weather extends Component {
getWeather () {
var self = this;
fetch('http://api.openweathermap.org/data/2.5/weather?zip=sl44jn,uk&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')
.then (function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
self.setWeather(data);
});
})
.catch (function (err) {
console.log('Fetch Error :-S', err);
});
}
setWeather (forecast) {
console.log(forecast);
this.setState({
forecast: forecast.name
})
}
componentWillMount () {
this.getWeather();
}
componentDidMount () {
// window.setInterval(function () {
// this.getWeather();
// }.bind(this), 1000);
}
render() {
return (
<h1>{this.state.forecast}</h1>
)
}
}
And this is the data object itself, right now I am simply trying to access the name attribute.
Looks like you forgot couple of things, in order to a Component to setState you need to bind it to this preferably in the constructor. You also need to set the initial state, in your case an empty object, and you can save the whole response in the object and access just the parts you want. have a look:
export default class Weather extends Component {
constructor() {
super();
this.state = {
forecast: {}
};
this.setWeather = this.setWeather.bind(this);
}
getWeather () {
let self = this;
fetch('http://api.openweathermap.org/data/2.5/weather?zip=sl44jn,uk&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')
.then (function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
self.setWeather(data);
});
})
.catch (function (err) {
console.log('Fetch Error :-S', err);
});
}
setWeather (forecast) {
this.setState({
forecast: forecast
});
}
componentWillMount() {
this.getWeather();
}
render() {
const { forecast } = this.state;
return (
<h1>{forecast.name}</h1>
)
}
}

Combining api request

I am new to Angular2 and just started to work with Http request and observables.
Previously I worked with .NET and MySql, and I am now trying to learn the best practice working with data from API’s.
I am used to join tables, and I would like to find the best way to combine json data.
In this example I want the user to fill a form and type his phone number.
The prefix of the phone number is a dropdownlist with country code and prefix f.ex. Germany +49
Therefor I need an object: { “Germany”:”49”, Cambodia:"855" ….}
I make 2 http request to country.io:
http://country.io/phone.json // e.g. DE: “Germany”
http://country.io/names.json // e.g. DE: “49”
From these 2 request I used the code below to make my new json object : myPhonePrefixObject
I think the code is too long, and that it must be possible to do it in a better way.
country-service.ts:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class CountryService {
constructor( private _http:Http) { }
getCountryCode(): Observable<any> {
return this._http.get('http://crossorigin.me/http://country.io/phone.json')
.map(countryCodes => countryCodes.json());
}
getPhonePrefix(): Observable<any> {
return this._http.get('http://crossorigin.me/http://country.io/names.json')
.map(phonePrefix => phonePrefix.json());
}
}
Code inside userform.component in where I import the CountryService
myPhonePrefixObject;
this.countryPhonePrefix()
.then((pp) => {
myPhonePrefixObject = pp;
})
.catch((err) => {
console.log(err);
});
private getCountryCode() {
return new Promise((resolve) => {
this._countryService.getCountryCode()
.subscribe(
res => resolve(res)
);
});
}
private getPhonePrefix() {
return new Promise((resolve, reject) => {
return this._countryService.getPhonePrefix()
.subscribe(
res => resolve(res),
error => reject(error)
);
});
}
private countryPhonePrefix() {
return new Promise((resolve, reject) => {
let cc: Object;
this.getCountryCode()
.then((cCode) => {
cc = cCode;
return this.getPhonePrefix()
})
.then((pPrefix) => {
let pp: Object = {};
Object.keys(cc).forEach((key, index) => {
pp[cc[key]] = pPrefix[key];
});
resolve(pp);
})
.catch((err) => {
reject(err);
});
});
}
.NET developer here too!
To deal with multiple streams, you will need aggregation methods. In this case, you want to yield the object based on the result of 2 streams (HTTP requests), the aggregation method you are looking for is combineLatest. It combines the 2 streams and let you define the output data based on 2 sources:
getCombinedData(): Observable<Data> {
return this.getCountryPhones().combineLatest(this.getCountryNames(),
(phoneData, nameData) => {
var resultData = {};
Object.keys(nameData).forEach((key) => {
resultData[nameData[key]] = phoneData[key];
});
return resultData;
});
}
Plunker: http://plnkr.co/edit/agUPNujG3NnbKI6J3ZVJ?p=preview