Axios store same information inside foreach - vue.js

I have an array of objects that is needed to be store in DB when clicking on a single button. Therefore I have used foreach loop and inside the loop, I did the AXIOS POST. AXIOS stores the same information/ object. all objects of the array are not saved is there any solution.
let arr = [
{
name:'abc',
co: 1
},
{
name:'def',
co: 2
},
{
name:'ghi',
co: 3
},
];
let fd = new FormData();
arr..forEach((element) => {
fd.append("name", element.name);
fd.append("co", element.co);
this.$http.post("po", fd, { headers: {
"Content-Type": "multipart/form-data",
},
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
});
WHEN MAPPING THE ARRAY as follows. an error occurs cannot read property co of undefined
let element= this.formList.map((obj) => obj);
// appending data
// axios POST
IT ONLY SAVES THE LAST OBJECT. WHAT I WANT IS EACH OBJECT SHOULD BE STORE

the mistake I did was putting the Axios inside the foreach, which overwrites the object each time it loops therefore only the last item gets stored. the working solution is below
save() {
this.StoreMulti(this.arr, 0);
}
StoreMulti(arr, i){
this.$http.post("po", fd, { headers: {
"Content-Type": "multipart/form-data",
},
.then((res) => {
if (i < arr.length - 1) {
this.StoreMulti(arr, ++i);
}
onsole.log(res.data);
})
.catch((err) => {
console.log(err);
});
}
THIS STORE THE ENTIRE ARRAY BY SENDING POST REQUEST ONE BY ONE

Related

vue axios, how to access response headers

Why can't I access the response headers below? They should be accessible on the response object, which I am unpacking into the data and headers variables. I am thinking it might be trying to access the headers on the Promise, instead of the resolved response object.
getDomains({ commit, state }) {
return new Promise(async (resolve, reject) => {
try {
const { data, headers } = await axios.get(`http://wordpress.api/wp-json/sslchkr/v1/author/${state.user.id}/domain`, {
headers: {
Authorization: `Bearer ${state.user.token}`
}
})
commit('SET_DOMAINS', data, headers)
resolve(data)
} catch(e) {
reject(e)
}
})
},
I solved this riddle by passing in the response object to SET_DOMAINS, it only takes one argument.
SET_DOMAINS(state, res) {
state.domains.domains = res.data
state.domains.totalDomains = res.headers['x-wp-total']
state.domains.totalPages = res.headers['x-wp-totalpages']
}

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,
});
},
};

Vuex state is sometimes empty (undefined), especially when I refresh the page and sometimes it works

Vuex state is sometimes empty (undefined), especially when I refresh the page. And sometimes it works.
action:
getSkills(context) {
let url = "/skills";
const headers = {
"x-api-key": process.env.VUE_APP_SIRH_X_API_KEY,
Authorization: localStorage.getItem("access_token"),
};
return axios({
method: "get",
url: url,
headers: headers,
}).then((response) => {
context.commit("getSkill", response.data.data.skills);
}).catch((e) => {
console.log(e);
});
},
getter:
Skills: (state) => state.Skills,
mutation :
getSkill(state, skills) {
state.Skills = skills;
},
state :
Skills: [],
and the vue :
computed: {
...mapState({}),
...mapGetters(["Candidate", "Skills"])
},
mounted() {
this.getSkills();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
},
methods: {
...mapActions(["attachSkillCandidate", "getSkills"]),
}
Can anyone help me to solve this issue ?
Thanks!
The getSkills action is performing an asynchronous request. You need to wait for the request to finish before you can access this.Skills otherwise the data will not be set yet.
You need async and await (the "modern" solution):
async mounted() {
await this.getSkils();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
}
or:
mounted() {
this.getSkils().then(() => {
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
});
}

(VUEJS) Access methods from Axios inside created

I have just a simple error which is confusing me almost 3 weeks.
my question is about, I want to return string from methods "idvideo" at the end of my axios API url, but nothing is happen.
as you can see on my code below.
I have been searching for solution and try an error for many times, but still never found any best answer that can help me out.
export default {
data() {
return {
errors: [],
videos: [],
items: []
}
},
methods: {
idvideo: function() {
const data = this.items
const result = data.map((item) => {
return {
fetchId: item.snippet.resourceId.videoId
};
}).sort((a, b) => b.count - a.count);
var i, len, text;
for (i = 0, len = result.length, text = ""; i < len; i++) {
text += result[i].fetchId + ",";
}
var x = text.slice(0, -1);
return(x);
}
// Fetches posts when the component is created.
created() {
// Ini adalah API utk playlist yang dipilih
axios.get("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLjj56jET6ecfmosJyFhZSNRJTSCC90hMp&key={YOUR_API_KEY}")
.then(response => {
// JSON responses are automatically parsed.
this.items = response.data.items
})
.catch(e => {
this.errors.push(e)
}),
// Ini adalah API utk data yang dipilih
axios.get('https://www.googleapis.com/youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics&key={YOUR_API_KEY}&id='+this.idvideo())
.then(response => {
// JSON responses are automatically parsed.
this.videos = response.data.items
})
.catch(e => {
this.errors.push(e)
})
},
}
I really appreciate any kind of solutions that can help me out. If you guys have best way to implement this function, let me know.
Sorry for my bad english and any mistakes. This is my very second time post question in this platform.
Thank you very much sir!
Since, they are asynchronous requests, I have following solution in my mind.
Solution:
Move the next axios call within the first axios call. This is because, only after first call, the 'items' will be retrieved and then it will assigned to this.items So next axios call will have the required data from idvideo() function.
export default {
data() {
return {
errors: [],
videos: [],
items: []
}
},
methods: {
idvideo: function() {
const data = this.items
const result = data.map((item) => {
return {
fetchId: item.snippet.resourceId.videoId
};
}).sort((a, b) => b.count - a.count);
var i, len, text;
for (i = 0, len = result.length, text = ""; i < len; i++) {
text += result[i].fetchId + ",";
}
var x = text.slice(0, -1);
return(x);
}
// Fetches posts when the component is created.
created() {
// Ini adalah API utk playlist yang dipilih
axios.get("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLjj56jET6ecfmosJyFhZSNRJTSCC90hMp&key={YOUR_API_KEY}")
.then(response => {
// JSON responses are automatically parsed.
this.items = response.data.items
// Ini adalah API utk data yang dipilih
axios.get('https://www.googleapis.com/youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics&key={YOUR_API_KEY}&id='+this.idvideo())
.then(response => {
// JSON responses are automatically parsed.
this.videos = response.data.items
})
.catch(e => {
this.errors.push(e)
})
}
})
.catch(e => {
this.errors.push(e)
}),
,
}

What is the correct way to use AsyncStorage to update state in React-Native?

I'm trying to make a GET request to a server to retrieve a list of products in JSON form. I then want to put the data into AsyncStorage so I can display the products in the view. What's the correct way to do this?
What I've researched:
on https://facebook.github.io/react-native/docs/asyncstorage.html , in the example, they explain how to retrieve a value from AsyncStorage, not set it and retrieve it at the same time
What I have:
componentDidMount () {
this.fetchProducts()
this._loadInitialState().done();
}
_loadInitialState = async () => {
try {
var value = await AsyncStorage.getItem('products')
if (value != null) {
this.setState({products: value});
}
} catch (error) {
console.log("error setting product list");
}
}
fetchProducts() {
fetch("http://localhost:3000/products",{
method: "GET",
headers: {
'Content-Type': 'application/json'
},
})
.then((response) => (response.json()))
.then((data) => setProductList(data));
}
setProductList(json_data) {
Async.setItem('products': json_data);
}
render() {
console.log(this.state.products)
//render view
}
-> this.state.products is null and I know for sure the server returns a response through curl. I'm new to react-native so perhaps my thinking is off. Could someone explain the correct way to do this or suggest an alternative method?
What I know
Async storage is a key value store where an app can place its data. This data can be put from async storage into the object's state and the view will update accordingly
Instead of setting and getting from async storage, you can just set it to state once you get the data from your fetch request:
componentDidMount () {
this.fetchProducts()
}
fetchProducts() {
fetch("http://localhost:3000/products",{
method: "GET",
headers: {
'Content-Type': 'application/json'
},
})
.then((response) => (response.json()))
.then((data) => setProductList(data));
}
setProductList(json_data) {
this.setState({ products: json_data }, () => { //Here
Async.setItem('products': json_data);
}
}
render() {
console.log(this.state.products)
//render view
}