Angular 4 wait till http.get execute to continue - json

I'm creating a new register form an app with Ionic and using ASP.Net(C#) as my API.
I want to check if user exists when the input blur event is activate.
The problem is that my code isn't waiting till the server returns a value to continue.
What am I doing wrong? Is there a way to do that?
THIS IS MY API CODE:
[HttpGet]
public JsonResult verifyEmail(string email)
{
var result = Domain.Repository.UserController.Find(email:email);
if (result != null)
{
return Json(new { erro = true, message = "Email already registered!" }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { erro=false,message = "Email is valid!" },JsonRequestBehavior.AllowGet);
}
}
I CREATED A PROVIDER TO MAKE THE HTTP REQUEST(authProvider):
getData(data,func)
{
return new Promise( (resolve,reject)=>{
this.http.get(apiUrl+func, {params:data})
.subscribe(
res=>{
resolve(res.json());
},
async (err)=>{
reject(err);
});
});
}
AND HERE IS MY register.ts code:
validate()
{
let validEmail;
validEmail= this.checkEmail();// I WANT THAT the "validEmail" receives returned value before continue.
return true;
}
AND THE LAST THING IS MY FUNCTION THAT WILL CALL THE PROVIDER:
checkEmail()
{
return this.authService.getData({email:this.model.email},"Account/verifyEmail").then((result)=>{
let response = <any>{};
response=result;
if(response.erro)
{
return response.message
}else
{
return true
}
},(err)=>{
this.toastService.presentToast("ERROR:"+err,"bottom",undefined,"toast-error");
});
}
Thanks in advance..

getData(data,func)
{
this.http.get(apiUrl+func, {params:data})
.map(res => {
return res.json();
})
.toPromise();
}
or with async/await
async getData(data,func)
{
let result = await this.http.get(apiUrl+func, {params:data})
.toPromise();
return result.json();
}
Now for the validate function:
async validate()
{
let validEmail;
await this.checkEmail();
return true;
}
Point is you cant jump from a sync function to an async or vice versa.
Validate needs to return a promise/observable because it is executes asynchronous functions.

Related

how to read properly a json string in react native

I sent to asyncStorage all the info as stringify,
i tried to parse it.
this is what i get from console log:
"{\"metadata\":{\"lastSignInTime\":1610728860334,\"creationTime\":1610728860334},\"phoneNumber\":null,\"displayName\":null,\"isAnonymous\":false,\"providerData\":[{\"email\":\"ad#ad.com\",\"phoneNumber\":null,\"uid\":\"ad#ad.com\",\"photoURL\":null,\"displayName\":null,\"providerId\":\"password\"}],\"email\":\"ad#ad.com\",\"emailVerified\":false,\"providerId\":\"firebase\",\"photoURL\":null,\"uid\":\"3lkoKoMxQSMKeSxFOyysESt3oKh1\"}"
and i need to get email and uid seperate.
how do I get in that object? i tried user.email or user.providerData.email non of them work.
any suggestion?
edited:
here is the object I get from firebase
let res = await auth().createUserWithEmailAndPassword(Email, Password)
if (res) {
console.log( "?", res)
this.setState({ userData: JSON.stringify( res.user) });
this.storeToken(JSON.stringify(res.user));
then I store the token in async:
async storeToken(user) {
console.log('set user register: ', user)
try {
await AsyncStorage.setItem("userData", JSON.stringify(user));
} catch (error) {
console.log("Something went wrong", error);
}
}
and I get the object from above.
const readData = async () => {
console.log('data === ')
try {
const data = await AsyncStorage.getItem('userData')
let _data = JSON.parse(data);
console.log('data === ', data)
If you share code block it'll be easy for us.
Here is general answer.
Console log shows its still in string format. I use this separate file to read and write json to AsyncStorage. You can either use this OR match to see your mistake.
import AsyncStorage from '#react-native-community/async-storage';
const Api = {
storeData: async function (name, value) {
try {
await AsyncStorage.setItem(name, value);
return true;
} catch (error) {
return false;
}
},
readData: async function (name) {
let value = null;
try {
value = await AsyncStorage.getItem(name)
return JSON.parse(value);
} catch (e) {
return [];
}
},
}
export default Api;
after few console log I was able to get it by double parsing the object.
let _data = JSON.parse(JSON.parse(data));
console.log('data === ', _data.email)
and seem to work.

Changed request does not work in angular 6

I have following function which calls the refresh service to get new token for authorization:
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
if(!this.isRefreshingToken) {
this.isRefreshingToken = true;
return this.authService.refreshToken()
.subscribe((response)=> {
if(response) {
const httpsReq = request.clone({
url: request.url.replace(null, this.generalService.getUserId())
});
return next.handle(this.addTokenToRequest(httpsReq, response.accessToken));
}
return <any>this.authService.logout();
}, err => {
return <any>this.authService.logout();
}, () => {
this.isRefreshingToken = false;
})
} else {
this.isRefreshingToken = false;
return this.authService.currentRefreshToken
.filter(token => token != null)
.take(1)
.map(token => {
return next.handle(this.addTokenToRequest(request, token));
})
}
}
When the response is not undefined and request is returned back it does not call the new request
Ok the thing was that the bearer was quoted like below:
But I have still one issue the request does not invoke the new request, when I refresh the page it gives data with new token, instead like I previously had unauthorized error.

How to access the value of this json token to store in in local storage

loginUser(user: any) {
return this.http.post(this.loginUrl, user)
.subscribe((success: any) => {
if(success) {
localStorage.setItem('access_token', success.token);
localStorage.setItem('token', JSON.stringify(success.token));
return true;
}
});
}
What is returned https://i.imgur.com/Km8X2CX.png
Result in storage https://i.imgur.com/FfsOTb5.png
I want to store the value of the token
Changing this to
localStorage.setItem('access_token', success);
localStorage.setItem('token', JSON.stringify(success));
Result - https://i.imgur.com/c9wMosF.png
you should set success.success.token instead.
Better to rename the response as response
loginUser(user: any) {
return this.http.post(this.loginUrl, user)
.subscribe((response: any) => {
if(response) {
localStorage.setItem('access_token', response.success.token);
// localStorage.setItem('token', JSON.stringify(response.success.token)); probably not needed.
return true;
}
});
}
You have unnecessary wrapping over the response object. Remove that or use response.success.token to get to the token string.
your code becomes:
loginUser(user: any) {
return this.http.post(this.loginUrl, user)
.subscribe((response: any) => {
if(response) {
localStorage.setItem('access_token', response.success.token);
return true;
}
});
}

TextDecoder failing in ES6 Promise recursion

I'm attempting to query an API which responds with a ReadableStream of XML.
The code below uses a recursive Promise. Recursive because it sometimes doesn't decode the stream in a singular iteration and this is whats causing my headache.
While I'm successfully fetching the data, for some reason the decoding stage doesn't complete sometimes, which leads me to believe it's when the stream is too large for a single iteration.
componentDidMount() {
fetch("http://thecatapi.com/api/images/get?format=xml&size=med&results_per_page=9")
.then((response) => {
console.log('fetch complete');
this.untangleCats(response);
})
.catch(error => {
this.state.somethingWrong = true;
console.error(error);
});
}
untangleCats({body}) {
let reader = body.getReader(),
string = "",
read;
reader.read().then(read = (result) => {
if(result.done) {
console.log('untangling complete'); // Sometimes not reaching here
this.herdingCats(string);
return;
}
string += new TextDecoder("utf-8").decode(result.value);
}).then(reader.read().then(read));
}
I think that the next iteration was sometimes being called before the current iteration had completed, leading to incorrectly concatenation of the decoded XML.
I converted the function from sync to async and as a regular recursive method of the component rather than a recursive promise with a method.
constructor({mode}) {
super();
this.state = {
mode,
string: "",
cats: [],
somethingWrong: false
};
}
componentDidMount() {
fetch("http://thecatapi.com/api/images/get?format=xml&size=med&results_per_page=9")
.then( response => this.untangleCats( response.body.getReader() ) )
.catch(error => {
this.setState({somethingWrong: true});
console.error(error);
});
}
async untangleCats(reader) {
const {value, done} = await reader.read();
if (done) {
this.herdingCats();
return;
}
this.setState({
string: this.state.string += new TextDecoder("utf-8").decode(value)
});
return this.untangleCats(reader);
}

how to update a variable in es6 inside a fetch function?

I have this code below:
let courses = '';
fetch(link)
.then(function(response) {
return response.json();
}).then(function(json) {
courses = json;
}).catch(function(ex) {
console.log('parsing failed', ex);
});
Using console.log(courses) prints out ''.
How do I set it to the retrieved json?
The fetch method is asynchronous, essentially, you will only have access to the json content in the courses variable after the fetch promise resolves. Try doing the following:
function synchronousCode(courses) {
console.log('courses', courses); // output json courses
}
fetch(link)
.then(function(response) {
return response.json();
})
.then(synchronousCode)
.catch(function(ex) {
console.log('parsing failed', ex);
});
One of the benefits of using the Fetch API is that you can neatly chain your methods instead of just having one "synchronousCode" function. Here's an example:
function asynchronouslyAnalyze(courses) {
return new Promise(function(resolve, reject) {
setTimeout(function () { resolve(courses) }, 1000);
});
}
function parse(courses) {
// do something with courses
return courses;
}
function print(courses) {
console.log('courses', courses); // output courses json
}
function toJSON(response) {
return response.json();
}
fetch(link)
.then(toJSON)
.then(asynchronouslyAnalyze)
.then(parse)
.then(print)
.catch(function(ex) {
console.log('parsing failed', ex);
});
I hope that helps!