using fetch with ES2015 modules in Canary - module

I'm trying out ES2015 modules in Chrome Canary Version 60.0.3102.0. My script.js file reads like this:
import {fetchJSON} from './functions/fetchJSON.js';
const configFile = 'config.json';
const init = () => {
fetchJSON(configFile)
.then((data) => { // code fails here at ln.7
console.log(data);
})
.catch(error => console.log(error));
};
init();
and my fetchJSON.js file reads like this:
export function fetchJSON(url) {
const fetchJSON = fetch(url)
.then(response => response.json())
.then(data => {
console.log(data); // data exists and is reported in the console
return data;
});
}
I'm getting the error:
script.js:7 Uncaught TypeError: Cannot read property 'then' of undefined
at init (script.js:7)
at script.js:14

Your fetchJSON function isn't returning anything. Because of that, when you try chaining a .then on the result of fetchJSON, you're getting the Uncaught TypeError - undefined.
Solution: return your Promise chain in your fetchJSON function:
export function fetchJSON(url) {
return fetch(url)
.then(response => response.json())
.then(data => {
return data;
});
}

Related

Testing Vue with Jest gives an error TypeError: Cannot read property 'then' of undefined

I have been trying to run a test in a file, but I am not even testing the function yet, but I keep getting an error TypeError: Cannot read property 'then' of undefined
The lines in the vue file look like this:
this.$store.dispatch($c.ACTION_FETCHDATA, payloadTradingAccounts).then((response) => {
if (response) {
self.$store.commit(`accounts/${$c.MUTATE_SETACCOUNTS}`, response);
self.isLoading = false;
}
});
and in actions, I got the following:
[$c.ACTION_FETCHDATA]({state, commit, rootState}, payload) {
return new Promise((resolve, reject) => {
let instance = axios.create({
baseURL: $c.DEFAULT_API_URL,
timeout: $c.DEFAULT_TIMEOUT,
headers: {
'X-Session-Token': rootState.accessToken
}
});
instance.get( payload.url, {
params: payload.params
}).then((response) => {
let rows = response.data.data;
resolve(rows);
}).catch((err) => {
onError(err, commit);
console.log(err);
});
});
},

How to get data's property value after axios.get call?

It's Vue.js app and the code looks as following:
getQrCodeUrl(paymentId) {
this.$axios.get(`${this.$config.server}/api/crm/payments/qr/${paymentId}/url`)
.then(responseUrl => {
console.log('responseUrl.data =', responseUrl.data)
console.log('responseUrl.data.url =', responseUrl.data.url)
})
.catch(error => {
...
})
},
I've got responseUrl.data, but responseUrl.data.url is undefined as in the screenshot below:
The screenshot shows you that responseUrl is an object with result and data properties. I believe it is the successful promise. By adding a .then(response => response.json()), you will have the data by itself as a JSON object.
Refactor the code as follows :-
getQrCodeUrl(paymentId) {
this.$axios.get(`${this.$config.server}/api/crm/payments/qr/${paymentId}/url`)
.then(response => response.json())
.then(response => {
console.log('response.url =', response.url)
})
.catch(error => {
...
})
},

React Native variable getting undefined before running method

I have a function that calls a method that is in my Helper.js file.
import { getTest } from '../../common/Helper';
...
myMethod() {
...
const test = getTest(this.state.myID);
console.log(test);
}
...
My Helper.js:
export const getTest = (pID) => {
axios.get('http://myserver.com/', {
params: {
method: 'getVacantUnits',
propertyID: pID
}
}).then((response) => {
console.log(response.data);
return response.data;
}).catch((error) => {
// handle error
console.log(error);
return 0;
});
};
It is odd because my output is:
undefined
myDataContent
It looks like that "const test" is receiving undefined before the getTest being run. Why is it happening?
Thanks
It's returning this first since it's not awaiting the result:
console.log(test);
2 easy ways to fix this I am showing below, first with promise:
const test = getTest(this.state.myID).then(response=> console.log(response)).catch(err => console.log(err))
Add in return as well since you need to return from outermost function
export const getTest = (pID) => {
return axios.get('http://myserver.com/', {
params: {
method: 'getVacantUnits',
propertyID: pID
}
}).then((response) => {
console.log(response.data);
return response.data;
}).catch((error) => {
// handle error
console.log(error);
return 0;
});
};
second using async await:
// add in await
export const getTest = async (pID) => {
return axios.get('http://myserver.com/', {
params: {
method: 'getVacantUnits',
propertyID: pID
}
}).then((response) => {
console.log(response.data);
return response.data;
}).catch((error) => {
// handle error
console.log(error);
return 0;
});
};
// here you are awaiting the response before you run console.log
const test = await getTest(this.state.myID);
console.log(test);
You can solve this in several other ways, but I think these are the 2 easiest. Basically think about the fact that those are run synchronously and the console.log executes before the function returns, so if you "wait" then it makes it so the console.log() is dependent on the first function executing first.

Parsing JSON in React Native fetch method doesnt work

Im trying to call an API with fetch from React Native App but itdoesnt log the response data (console.warn('data', data)) for some reason. It prints the 'call to getArtists' log but then nothing happens.
const URL = 'https://jsonplaceholder.typicode.com/posts'
function getArtists(){
console.log('call to getArtists')
return fetch(URL)
.then(response => response.json())
.then(data => {
console.warn('data', data)
})
}
Code is available here: https://snack.expo.io/rkzea2Zlm at components/api-client.js
What am I doing wrong?
First in your "api_client.js", put a return inside like the code bellow.
function getArtists(){
console.log('call to getArtists')
return fetch(URL)
.then(response => response.json())
.then(data => {
return data
})
}
In your App.js just do that inside componentWillMount.
componentDidMount(){
getArtists()
.then(data => {
alert(JSON.stringify(data))
});
}

Access vuex store from catch block

Im trying to put error messages from an api call and put it in the vuex store, but im not sure how to do it.
I have this in a "method" within a vue file
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch(function(error) {
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});
Im getting the following error:
Uncaught (in promise) TypeError: Cannot read property '$store' of undefined
Probably your function is reassigning the value of this.
Try changing it to:
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch(error => { // <= HERE IS THE CHANGE!!
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});
Read about the difference between function(arg) {}and (arg) => {}here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
You are using a function instead of an arrow function on the catch block so this inside that block has a different scope.
Just replace the function with an arrow function.
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch((error) => {
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});