Console.log shows as undefined after subscribing to provider in Ionic3 - javascript

I'm trying to get data using the Spotify api in an Ionic 3 app that I'm building, but for some reason when I try to console.log the data, it is showing as undefined. Let me show some code and then explain further. Here is my getData():
getData(){
console.log("getData has been called!!!");
return this.http.get(this.dataUrl).map((res) => {
res.json(),
console.log(res.json())//this works fine
});
}
The above code works fine. It is in a provider/service called 'soundData'. The problem is with the following bit of code. When I try to console.log the data, it shows as undefined in my browser:
ionViewDidLoad(){
this.soundData.getData().subscribe(
returnedData=> {
this.data = returnedData;
console.log(this.data) //this shows as undefined
},
returnedError => {
this.error = returnedError;
});
}
I don't really see what I'm doing wrong. It seems that everything should be working fine, but maybe I'm missing something since I'm new to TypeScript and Ionic.

You need to return from .map
getData() {
console.log("getData has been called!!!");
return this.http.get(this.dataUrl).map((res) => {
console.log(res.json());//this works fine
return res.json();
});
}
A more idiomatic way would be to use the .do method to perform the logging operation separately as in
getData() {
return this.http.get(this.dataUrl)
.map(res => res.json())
.do(json => console.log(json));
}

You can simply follow the below pattern.
Your service method
getData(): Observable<your-data-type>{
return this.http.get(this.dataUrl).map(res => res.json());
}
Your subscribe method
getData(): your-data-type {
this.soundData.getData().subscribe(
returnedData => {
this.data = returnedData;
},
err => {},
() => {}
);
}

Related

Exception handling in promise chain

I have a code with multiple promise chain as shown below
.then(function(response) {
//my code
})
.then(function(app) {
//my code
})
.then(function() {
//my code
})
Have added exception handling to each of them as shown below so that if one breaks the rest chain continues.
Is this the correct way of handling exception for multiple chain blocks, or any best practice can be followed to handle the exceptions so that the code execution doesn't break if one fails.
.then(function(response) {
//my code
})
.catch(e => {})
.then(function(app) {
//my code
})
.catch(e => {})
.then(function() {
//my code
})
.catch(e => {})
If your code can accommodate the error (whatever it is) that's occurring early on, this can be a reasonable way of doing it, but I'd always have to look twice at it in a code review because it's fairly unusual for the code to be able to just ignore errors like that. The code is roughly equivalent to:
try {
//my code
} catch (e) {
}
try {
//my code
} catch(e) {
}
try {
//my code
} catch(e) {
}
...but using promises instead. So it's a bit suspect, but can be correct, for the same reasons the above is a bit suspect but can be correct if you need to do a series of things, one at a time, and have each of them done even if the previous one fails.
Beware that it means app in the subsequent fulfillment handler will be undefined:
.then(function(response) {
//my code
})
.catch(e => {})
.then(function(app) { // <=== `app` is `undefined` here
//my code
})
.catch(e => {})
.then(function() {
//my code
})
.catch(e => {})
Answer posted before, is correct.
I just want to insert my 2 cents.
You can have some fun with one helper function (or use something more fancy like whole Either monad thingy from fp-ts package)
const run = async (fn) => {
try {
const result = await fn()
return [result, null]
} catch (err) {
return [null, err]
}
}
and write code without try\catch or .then\.catch
const [response, error] = await run(() => fetch('asdfasdf'))
const app = buildApp(response.ok ? await response.json() : { fallback: 'data' })
const [appResponse, appError] = await run(async () => {
await app.compileTemplate()
return app.buildResponse()
})
if (appResponse) {
// ...
}
Or more useless approach, you can throw a custom error, so your first .catch block will be able to do something.
class AppFromResponseError extends Error {
constructor(message, fallbackApp) {
super(message)
this.name = "ResponseError"
this.app = "fallbackApp"
}
}
builder
.then(function(response) {
if (response.ok !== true)
throw new AppFromResponseError('not ok', minimalApp)
})
.catch(e => {
if (e.app) return e.app
})
.then(app => { /* some kind of app will be here */})

component's render() is not getting invoked after updating mobx store value

Updating store before fetching data from server, works fine.. But after fetching data from from server and updating store, render() method not getting invoked
code snippet
#action
static getPartner(partnerParams) {
store.invitationDetails.invitingOrgPartnerName = ""; // here render() is getting invoked
fetchPartner(partnerParams)
.then((data) => data.json())
.then(function (result) {
if (result.success) {
if (result.alreadyPartner) {
runInAction(() => {
store.invitationDetails.invitingOrgPartnerName = result.partnerName; // here render() is NOT getting invoked
});
}
}
})
.catch((e) => {
console.info("Failed getting partners", e);
});
}
Mobx works perfectly in most of the cases but not always
You should use extendObservable
Please follow this ExtendObservable

ReactJS - Javascript try/catch shows an error in the console

I'm pretty new on React and I'm learning this language nowadays.
For this purpose I'm building a test project on which I try to encounter the main classical issues and looking to solve it.
For most of React developpers, there are no difficulties in following code but I will give a few details for better comprenhension.
I have a portion of javascript code that is returning a list of articles from a Symfony Backend API only if user is authorized for getting it (Authorization via JWT will be done later). A getArticles function returns a Promise that tries to get the articles from the Symfony backend inside a try {} catch (error) {} block.
Voluntarily, Authorization token is not send to trigger an error in the query.
As the axios.get is located inside a try {} catch (error) {} block, I am surprised that an error appears in the console for the request. It doesn't impact the behavior but it is not very clean to have these errors in the console.
My question(s) :
Why an error appears in the console while the code is inside a try/catch ? To get a cleaner app behavior, is there a way to avoid having this error in the console ? I have found other React try/catch issues but I didn't deduct the similarity with my issue. Am I missing something ?
Thanks in advance ;-)
I am aware that my code could be refactored, do not hesitate to suggest any good practice
componentDidMount(){
/*To be prepared to attach JWT token*/
axios.interceptors.request.use(req => {
return req;
});
const getArticles = async() => { return new Promise( (resolve, reject)=> {
try{
const data = axios.get('https://xxxxx/api/articles');
resolve(data);
} catch (err) {
reject(err);
}
});
}
getArticles().then(res => {
const articles = res.data.data.items;
this.setState( {errorOnArticlesLoading:false, articles: articles } );
})
.catch(error => {
this.setState( {errorOnArticlesLoading:true} );
});
}
You can try in this way and Async functions itself returns a promise, you don't need to return a new Promise manually.
async componentDidMount() {
try {
/*To be prepared to attach JWT token*/
axios.interceptors.request.use(req => req);
const getArticles = async () => {
try {
const data = axios.get('https://xxxxx/api/articles');
this.setState({ errorOnArticlesLoading: false, articles: data.data.items });
} catch (err) {
this.setState( {errorOnArticlesLoading:true} );
}
};
await getArticles()
} catch(err) {
console.log('Handled root error')
}
}
It seems that there are no solutions to avoid the 401 http error code in the console because it it printed by Chrome itself: See discussion here. So the following code cannot avoid the 401 error status to be printed in the console.
componentDidMount(){
/*To be prepared to attach JWT token*/
axios.interceptors.request.use(req => {
return req;
});
const getArticles = async() => {
const data = await axios.get('https://xxxx/api/articles');
return data;
}
getArticles().then(res => {
const articles = res.data.data.items;
this.setState( {errorOnArticlesLoading:false, articles: articles } );
})
.catch(error => {
this.setState( {errorOnArticlesLoading:true} );
});
}

Data coming in Service Response but showing 'undefined' from where it is called - JavaScript | React

I am calling an API which in turns gives me data back. When I am trying to store that data in variable and then console.log, the result is undefined. Why is it happening? How to fix this?
someService.js
getItems: () => {
axios.get('https://jsonplaceholder.typicode.com/users/')
.then( response => {
console.log(response.data); //gives me an array of 10 items
return response.data;
})
}
someReducer.js
case "GET_ITEM_LIST": {
let data = getItemsAPI.getItems();
console.log(data); //gives undefined
return {
...state,
items: data
}
}
With your case, you fetching API from server as asynchronous:
Try to you async/await like this:
export default {
fetch: async (state, { type, payload }) => {
// ....
case "GET_ITEM_LIST": {
let data = await getItemsAPI.getItems();
console.log(data); // you will see data here
return {
...state,
items: data
}
}
// ....
}
}
You need to return promise and await for result as its async. Notice return before axios that returns promise that you can work on. (I'm editing in mobile and I guess formatting is bad. If it worked, will update later)
getItems: () => {
return axios.get('https://jsonplaceholder.typicode.com/users/')
.then( response => {
console.log(response.data); //gives me an array of 10 items
return response.data;
})
}
Then, await getItems() or getItems().then() wherever you need.

How to retrieve axios data from the promise

I am currently trying to query my backend using axios and to that specific address I am sending with res.json an object and I am also able to see it with postaman. But when trying to build a function to retrieve it, my object looks like:Promise {pending}. How can i refactor my function ?
isAuthenticated = () => {
return axios.get('https://myaddress/authenticate')
.then(function (response) {
return response.data
})
};
You need to call the promise like so:
isAuthenticated().then(result => console.log(result))
.catch(error => console.log(error));
Use This code and let me know if still, you face a problem.
const isAuthenticated = () => {
return axios.get('https://myaddress/authenticate').then(response => {
// returning the data here allows the caller to get it through another .then(...)
return response.data
}).catch(error => console.log(error));
};
isAuthenticated().then(data => {
response.json({ message: 'Request received!', data })
})
here is similar questions as yours: Returning data from Axios API || Please check it as well.

Categories

Resources