Vue.js remove object data if null or empty - javascript

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 )
....

Related

How to use map() in vue.js 2

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

VUEX mutate array data each request

I have some data from an API that I am storing in VUEX and then displaying in the UI. On initial page load there is a request that pulls in the initial data and displays. All works well. My issues is When I now submit a form input for another request using an event handler I am just pushing to the array and it is adding to the array (which makes sense) and creates another instance below the current data which I do not want. Is there a way to actually CHANGE / MUTATE the current data that is in the array and update the UI with the new values?
STORE
import { createStore } from 'vuex';
import axios from 'axios';
export default createStore({
state: {
ipData: [],
currentIP: '',
},
mutations: {
SET_CURRENT_IP(state, currentIP) {
state.currentIP = currentIP;
},
SET_IP_DATA(state, ipData) {
state.ipData.push(ipData);
},
},
});
FORM SUBMIT
methods: {
async submitForm() {
const isFormValid = await this.v$.$validate();
if (!isFormValid) return;
axios
.get(`${this.url}${this.getIP}`, {
headers,
})
.then((response) => {
this.$store.commit('SET_IP_DATA', response.data);
})
.catch((error) => {
console.log(error.response);
});
},
},
VUEX OBJECT:
ipData:Array[1]
0:Object
as:Object
domains:Array[5]
ip:"8.8.8.8"
isp:"Google LLC"
location:Object
city:"Mountain View"
country:"US"
geonameId:5375480
lat:37.38605
lng:-122.08385
postalCode:"94035"
region:"California"
timezone:"-07:00"
If your ipData is array of object, you can create another mutation for updating your array (use id or some other identifier to match right object):
UPDATE_IP_DATA(state, payload) {
state.ipData = [
...state.ipData.map((item) =>
item.id !== payload.id
? item
: {
...item,
...payload,
}
),
];
}

Unable to set Vue.js data values inside axios response

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

Vue, reassigning and reusing response values for different objects

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

React - Create objects from API call and store in one big object

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

Categories