Vuex store cannot be used inside axios handler - vue.js

I have method being successfully called by a button in my Vue component:
methods: {
goTestMe() {
console.log(this.$store.state.lang+' 1')
let url = 'some api url'
let headers = { headers: { 'Content-Type': 'application/json' } }
this.$axios
.get(url, headers)
.then(function(response) {
console.log('here')
console.log(this.$store.state.lang+' 2')
})
The problem is that the output of this is:
en-us 1
here
When it should be:
en-us 1
here
en-us 2
Clearly, the reference to this.$store.state is failing in the then() handler of the axios call.
Why is this? How can I send data received by my axios request to the Vuex store?

when you add the callback in the normal function you can't access the global object so you need to change it to an arrow function
methods: {
goTestMe() {
console.log(this.$store.state.lang+' 1')
let url = 'some api url'
let headers = { headers: { 'Content-Type': 'application/json' } }
this.$axios
.get(url, headers)
.then((response) => { // change it to arrow function
console.log('here')
console.log(this.$store.state.lang+' 2')
})
}

Related

Console.log useState causes it to fire multiple times - React Native

I have the following function. If I try to console.log locationData my console gets overflooded because it logs it multiple times.
function GetGoogleData(){
const [locationData,setLocationData] = React.useState(undefined);
let APIURL = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${locationID}&key=xxxxxxxxxxxxxxxxxxxxxxxxxxx`;
let headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
fetch(APIURL,{
method: 'POST',
headers: headers,
})
.then((Response)=>Response.json())
.then((Response)=>{
setLocationData(JSON.stringify(Response))
});
console.log(LocationData)
}
Have a try by moving the API call inside the Life Cycle hook useEffect of React.
Ex.
function GetGoogleData(){
const [locationData,setLocationData] = React.useState(undefined);
useEffect(() => {
let APIURL = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${locationID}&key=xxxxxxxxxxxxxxxxxxxxxxxxxxx`;
let headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
fetch(APIURL,{
method: 'POST',
headers: headers,
})
.then((Response)=> Response.json())
.then((Response)=>{
setLocationData(JSON.stringify(Response))
});
}, [])
useEffect(() => {
if (locationData) {
console.log('locationData : ', locationData)
}
}, [locationData])
}
The first useEffect will only executed first mount of component and the second useEffect will call every update of the locationData State changes.

axios cancellation caught inside of then() instead of catch()

I making a multi-upload file form.
Upon user cancellation, once the corresponding axios call get cancelled using cancel(), I having a weird behaviour. My axios call get caught inside the then() whereas it should be caught inside of catch(). The response inside of then() returns undefined.
I am having a hard time figuring if I did something wrong on the front-end part, I think my call is may be missing some headers or maybe it's on the backend part ?
const payload = { file, objectId: articleId, contentType: 'article' };
const source = axios.CancelToken.source();
// callback to execute at progression
const onUploadProgress = (event) => {
const percentage = Math.round((100 * event.loaded) / event.total);
this.handleFileUploadProgression(file, {
percentage,
status: 'pending',
cancelSource: source,
});
};
attachmentService
.create(payload, { onUploadProgress, cancelToken: source.token })
.then((response) => {
// cancelation response ends up here with a `undefined` response content
})
.catch((error) => {
console.log(error);
// canceled request do not reads as errors down here
if (axios.isCancel(error)) {
console.log('axios request cancelled', error);
}
});
the service itself is defined below
export const attachmentService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api
.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
})
.then((response) => {
console.log(response, 'cancelled request answered here as `undefined`');
return response.data;
})
.catch((error) => {
// not caught here (earlier)
return error.data;
});
},
};
cancellation is called upon a file object doing
file.cancelSource.cancel('Request was cancelled by the user');
As suggested by #estus-flask in a comment, the issue is that I was catching the error inside of the service (too early). Thank you!
export const articleService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
});
},
};

Put API KEY in axios

I just started learn React but I have problem when I trying to make a request to the CoinMarketCap API with axios and tried several ways to set my API key. I have also also tried on Postman but message appears API key missing.
export const apiBaseURL = 'https://pro.coinmarketcap.com';
Tried like this
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map`,
{ headers =
{ 'X-CMC_PRO_API_KEY': 'apicode', }
})
this
dispatch({ type: FETCHING_COIN_DATA })
let config = { 'X-CMC_PRO_API_KEY': 'apicode' };
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map`, { headers: config })
and this
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map?X-CMC_PRO_API_KEY=apicode`)
Thank you
The short answer to adding an X-Api-Key to an http request with axios can be summed up with the following example:
const url =
"https://someweirdawssubdomain.execute-api.us-east-9.amazonaws.com/prod/custom-endpoint";
const config = {
headers: {
"Content-Type": "application/json",
},
};
// Add Your Key Here!!!
axios.defaults.headers.common = {
"X-API-Key": "******this_is_a_secret_api_key**********",
};
const smsD = await axios({
method: "post",
url: url,
data: {
message: "Some message to a lonely_server",
},
config,
});
Adding the key to the default headers was the only way I could get this to work.
Use CMC_PRO_API_KEY as a query parameter, instead of X-CMC_PRO_API_KEY:
dispatch({ type: FETCHING_COIN_DATA })
return axios.get(`${apiBaseURL}/v1/cryptocurrency/map?CMC_PRO_API_KEY=apicode`)
I realize this has been solved; for the sake of alternatives here is how I did it. I created a instance of axios in /includes/axios:
import axios from "axios";
const instance = axios.create({
baseURL: "https://example.com/api",
headers: {
"Content-Type": "application/json",
"x-api-key": "****API_KEY_HERE****",
},
});
export default instance;
Now axios can be imported anywhere in the project with the give configuration. Ideally you want to add your secret to the ENV variable for security reasons.

FormData as payload to vuex action

I need help. There is anyway to send FormData as payload for Vuex Action?
methods: {
...mapActions({
sendMessage: 'modules/modal/send_message'
}),
Send() {
this.End = !this.End
this.AutoClose()
this.msg.append('name', this.Name)
this.msg.append('phone', this.Phone)
console.log(this.msg)
this.sendMessage(this.msg)
},
And in Actions
const actions = {
send_message(payload) {
Axios({
method: 'post',
url: 'http://localhost:8080/api/content/create?type=Emails',
data: payload,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
}
But server responding:
[Create] error: no multipart boundary param in Content-Type
Add an empty {} as first argument to your action and it should work.
const actions = {
send_message({}, payload) {
...
Action handlers receive a context object which exposes the same set of methods/properties on the store instance, so you can call context.commit to commit a mutation, or access the state and getters via context.state and context.getters.
Reference

Problem with PUT request in axios with vue.js

I'm building a smart home application. I have a problem with sending PUT request to my rest api (I building it with flask), but when I try send request it gives me HTTP 400 error (( Uncaught (in promise) Error: Request failed with status code 400 )) . Can you help me?
import axios from 'axios';
export default {
data: function() {
return {
value: 0,
lampName: 'Kitchen',
};
},
mounted () {
axios
.get("http://127.0.0.1:5000/lamp/" + this.$route.params.id)
.then(response => (this.value = response.data))
},
methods: {
updateValue () {
axios
.put('http://127.0.0.1:5000/lamp/' + this.$route.params.id,
{value: this.value},
{headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
}
}
}
try to add the method field to the form and send it in post way like this
formData.append('_method', 'PUT')
then try to send the data regularly
I think it work like this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
import axios from 'axios';
export default {
data: function() {
return {
value: 0,
lampName: 'Kitchen',
};
},
mounted () {
axios
.get("http://127.0.0.1:5000/lamp/" + this.$route.params.id)
.then(response => (this.value = response.data))
},
methods: {
updateValue () {
let formData = new FormData();
formData.append("value", this.value);
formData.append("lampName", this.lampName);
formData.append('_method', 'PUT');
axios
.post('http://127.0.0.1:5000/lamp/' + this.$route.params.id,
formData
})
}
}
}
</script>
So this is the failing request:
axios
.put('http://127.0.0.1:5000/lamp/' + this.$route.params.id,
{value: this.value},
{headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
I don't know what your server is expecting but you're setting a content-type of application/x-www-form-urlencoded while sending JSON data. It seems likely this mismatch is the cause of your problems. You should be able to see this if you inspect the request in the Network section of your browser's developer tools.
If you need to use application/x-www-form-urlencoded then I suggest reading the axios documentation as you can't just pass in a data object like that:
https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
In short, you need to build up the body string manually, though there are utilities to make that less onerous.
If you actually want JSON data then just remove the content-type header. Axios should set a suitable content-type for you.
Pass your method as post method and define put in form data formData.append('_method', 'PUT') .
updateValue () {
axios
.post('http://127.0.0.1:5000/lamp/' + this.$route.params.id,
{value: this.value, _method: 'PUT'},
{headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
}