I have a working vue function with an axios call but I need to define some of my response values differently and reuse them for an object without changing the overall structure. I currently have:
data () {
return {
dateEvents: [],
events: [
],
},
created() {
this.fetchItems();
},
methods: {
fetchItems() {
axios.get('/home/items')
.then(response => {
// handle success
console.log(response.data)
this.dateEvents = response.data
this.events = response.data
})
The problem is, I need to keep my current format for dateEvents but map these values to different names for the events object.
So right now my response.data is item_id, item_title, item_available which I still need for dateEvents. But for events I need to map it so that events.title = item_title, events.start = item_available
I tried this but it gives me undefined
axios.get('/home/items')
.then(response => {
// handle success
console.log(response.data)
this.dateEvents = response.data
this.events.title = response.data.item_title
this.events.start = response.data.item_available
})
How can I keep the general structure but only change the assignments for my events object?
You should map your response.data array to make new format array like this
this.events = response.data.map(({ item_title, item_available, ...item }) => ({
...item,
title: item_title,
start: item_available
}))
Related
Im start learning vue.js and ive got some troubles. I need to use dictionary analog in js. Its called map. but i dont know where i should define it. I need to use it in checkDevices() method and in HTML code
P.S. Sorry for my English
export default {
data: () => ({
}),
devicesList: new map(
"varNameOne", false,
"varNameTwo", false,
"varNameThree", false,
),
methods: {
async checkDevices () {
let response = await axios.get(`/some/api`)
console.log("res.data: ", response.data);
devicesList.forEach((values, keys) => {
console.log("Key: ", keys, "Value: ", values);
})
}
}
}
ive trying to define it before export default like this: let devicesList = new map(...);, but it doesnt work.
In axios.get(`/some/api`) ive got response frome server with data (response.data):
device1: true
device2: false
device1: true
I need take it frome response in key-value pair for using in UI like
device1 connected
device2 disconnected
divice3 connected
I don't know the JSON of your Axios response so you need to update checkDevices function to match the key values. there is no need to use map above export default. you can do this in mounted function.
export default {
data:function(){
return {
devicesList:[]
}
},
mounted:function(){
this.devicesList = new Map();
this.devicesList.set('device1', false);
this.devicesList.set('device2', false);
this.devicesList.set('device3', false);
},
methods: {
async checkDevices () {
let response = await axios.get(`/some/api`)
console.log("res.data: ", response.data);
devicesList.forEach((values, keys) => {
console.log("Key: ", keys, "Value: ", values);
//Please Use YOUR RESPONSE.data here to update the device List
})
}
}
}
i am sending object data to some api, i have many states, and not everyone is required everytime, so, i want to remove some data from object if it is null or empty string, how can i do this?
export default {
methods: {
sendData() {
axios
.post("api", this.$store.state.data)
.then((response) => console.log(response))
.catch((error) => console.log(error));
console.log(this.$store.state.data);
},
},
mounted() {
this.sendData();
},
};
here, where i have store state data, i need to send only the filled values and not everything with empty values too, how can i realize this?
Try to use the reduce method applied on object keys the return the object with non-empty fields:
export default {
methods: {
sendData() {
let filledData = Object.keys(this.$store.state.data).reduce((acc,curr)=>{
if(data[curr]){
acc[curr]=data[curr]
}
return acc;
},{})
axios
.post("https://covid19.devtest.ge/api/create", filledData )
....
I have created an axios request to my api for two routes. Using the response data I sort posts into the correct columns inside an array. This all works as it should but then when I come to assigning the value of this array to an array inside data() i get the following error;
TypeError: Cannot set property 'boardPosts' of null
at eval (SummaryBoard.vue?2681:90)
at wrap (spread.js?0df6:25)
So I figured maybe something was wrong with the array I was trying to assign. So I tried to assign boardPosts a simple string value and I still get the same error. Why can I not set the value of boardPosts inside my axios response?
my code;
import axios from 'axios';
export default {
name: 'SummaryBoard',
data() {
return {
boardPosts: '',
}
},
created() {
this.getBoardData();
},
methods:
getBoardData() {
function getBoardColumns() {
return axios.get('http://localhost:5000/api/summary-board/columns');
}
function getBoardPosts() {
return axios.get('http://localhost:5000/api/summary-board/posts');
}
axios.all([getBoardColumns(), getBoardPosts()])
.then(axios.spread(function(columnData, postData) {
let posts = postData.data;
// add posts array to each object
let columns = columnData.data.map(obj => ({...obj, posts: []}));
posts.forEach((post) => {
// If column index matches post column index value
if(columns[post.column_index]){
columns[post.column_index].posts.push(post);
}
});
console.log(columns);
this.boardPosts = 'hello';
}))
.catch(error => console.log(error));
}
}
}
That's because you're using not using an arrow function in axios.spread(...). This means that you do not preserve the lexical this from the VueJS component, as function() {...} will create a new scope for itself. If you change it to use arrow function, then the this in the callback will refer to your VueJS component instance:
axios.all([getBoardColumns(), getBoardPosts()])
.then(axios.spread((columnData, postData) => {
// Rest of the logic here
}))
.catch(error => console.log(error));
I have a program that uses Axios to get data with API calls. I want to store the result as a object in my this.state.matrixDictionary variable. but everytime i make another API call the previous object gets overwritten. I want to create something like this
this.setState({
matrixDictionary: {
[0]: result,
}
})
Then next time i make another api call to get other result i want it to be like this:
this.setState({
matrixDictionary: {
[0]: result,
[1]: result,
}
})
But i dont want to add the [1] manually, i want it to be created depending on how many times i make the API call to store the objects. If i make 5 calls then the object should be now [0],[1],[2],[3],[4] so i can easily keep track of the objects and change their values later.
How is this best achieved?
fetchDataAPI(APIUrl){
this.setState({ isLoading: true });
console.log("Fetching from: " + APIUrl);
return axios.get(APIUrl,{
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
})
.then(result => {
this.setState({isLoading: false});
console.log(result.data);
return result.data;
})
.catch(error => {
this.setState({error, isLoading: false })});
}
UPDATE
I used the fix from Roman Batsenko, Next question is how do I then change a property in that object and put it back in setState.
I guess good practice is to use JS Spread syntax for that like ...state.
It depends on the format of answer from your API but I think it would be not so hard to achieve this with:
axios.get(APIUrl,{
/* ... */
})
.then(result => {
this.setState({
isLoading: false,
matrixDictionary: [...this.state.matrixDictionary, result.data]
});
})
make an array of object in your intial state like
this.state = {
matrixDictionary: []
}
and when you call your api push your response object in array so that will store always in another index and finally you make array of objects.
this.setState({ matrixDictionary: result.data});
it may help you.
Why not save the objects in an array, so you can have them in order:
in the constructor:
this.state = {
matrixDictionary: []
}
in your API call:
this.setState(prevState => ({
values: prevState.matrixDictionary.concat(result.data),
}));
You can access them like this:
this.state.matrixDictionary[0] // your first api call
this.state.matrixDictionary[1] // your second api call
this.state.matrixDictionary[2] // your third api call
I have a graphql schema that looks like this :
type User {
entries(status: EntryStatus): [Entry]
}
type Mutation {
updateEntry(status: EntryStatus): Entry
}
I can filter the list of entries by status (which is an enum) and I can update the status of an entry. I'd like to update the store when the status is updated so that the entry appears in the right list (entries(status: FOO) to entries(status: BAR)).
I know I can update the store with the update method.
const withMutation = graphql(updateEntryMutation, {
props: ({ mutate }) => ({
updateEntry: updateEntryInput =>
mutate({
variables: { updateEntryInput },
update: (proxy, newData) => {
// update data here
// Which would involve removing the entry from its previous filtered "list", and adding it to the one with the new status
})
})
});
But how can I know from which list to remove the entry since I don't have access to the old data (previous entry.status) from update ?
(apart from enumerating all lists by status and removing the updated entry if I find it...)
You need to store.readQuery() first, then write the new data to the store.
Kinda like this:
const EntriesQuery = 'yourQueryHere';
const withMutation = graphql(updateEntryMutation, {
props: ({ mutate }) => ({
updateEntry: updateEntryInput =>
mutate({
variables: { updateEntryInput },
update: (store, { data: { updateEntry }}) => {
const data = store.readQuery({ query: EntriesQuery });
data.entries.push(updateEntry)
store.writeQuery({ query: EntriesQuery, data })
})
})
});