check value is object when updating state [duplicate] - javascript

This question already has answers here:
Finding Variable Type in JavaScript
(12 answers)
Closed 5 years ago.
I am sending the following data to my reducer:
const data = {
value: { age, gender, ethnicity },
field: 'accessCode',
actionType: 'ADD_DETAILS',
};
this.props.dispatch(formHandler(data));
How can I check to see if the value prop is a single value, or an object with three values?
My action:
export function formHandler(data) {
return function(dispatch) {
// check data.value is an object with three value
if (..) {
this.props.dispatch(
showError({
type: 'SHOW_MODAL',
modalType: 'SHOW_ERROR',
})
);
} else {
dispatch({
type: data.actionType,
field: data.field,
value: data.value,
});
}
};
}
My reducer to update state:
switch (action.type) {
case ADD_LANGUAGE:
case ADD_ACCESSCODE:
case ADD_ACCESSCODE:
case ADD_DRINKS_CONCERN:
return {
...state,
[action.field]: action.value,
};
case ADD_DETAILS:
return {
...state,
...action.value,
};

Concerning the comment of how to check, this could be a start.
if (typeof(data.value) === 'object' && Object.keys(data.value).length === 3)
I'm not exactly sure how specific your needs are (does it need to be exactly 3 keys for example), but feel free to expand and I can chime in.

If you are okay using the Object prototype, you can test using this:
Object.getOwnPropertyNames(data).length
Object.getOwnPropertyNames returns an array with all property values with a length property of it's own included.

Related

How to destructure nested data returned from useQuery? [duplicate]

This question already has an answer here:
ES6 deep nested object destructuring
(1 answer)
Closed 1 year ago.
I have an Apollo query:
const { error, loading, data: user } = useQuery(resolvers.queries.ReturnUser, {
variables: { userId: parseInt(id) },
});
The data object returned from the query has another object called returnUser. So the actual object is:
data: {
returnUser: {
name: 'Some Name'
}
}
In my JSX I want to output the data:
return (
<div>
{ user ?
<p>Profile {user.returnUser.name}</p> :
<div>User not found</div> }
</div>
);
As you can see I need to access the returnUser object on the user object to get the actual user data. This is not great. Is there any way to destructure the data object from the useQuery so I can assign the nested object to user?
//edit: While this looks like a duplicate question, the answer is different due to the async nature of useQuery. If you don't set a default value you'll get an error.
Got the answer thanks to #Pilchard:
const {error, loading, data: {returnUser: user} = {}} = useQuery(resolvers.queries.ReturnUser, {
variables: {userId: parseInt(id)},
});
You can follow the same nesting while deconstructing the data.
e.g.
const data = {
anotherLevel: {
returnUser: {
name: 'Some Name'
}
}
}
const { anotherLevel: {returnUser: { name }}} = data;
console.log(name); // prints Some Name

spread operator in javascript with key in array [duplicate]

This question already has an answer here:
Dynamic object property names?
(1 answer)
Closed 1 year ago.
Going over this code in github https://github.com/WebDevSimplified/postman-clone, I simply do not understand below portion
function keyValuePairsToObjects(container) {
const pairs = container.querySelectorAll('[data-key-value-pair]')
return [...pairs].reduce((data, pair) => {
const key = pair.querySelector('[data-key]').value
const value = pair.querySelector('[data-value]').value
if (key === '') return data
return { ...data, [key]: value }
}, {})
}
{...data, [key]: value} Why is key inside of an array?
Key is not an array, this is the syntax for using a variable name as the key, like the obj["prop"] syntax, { ["prop"]: true } is like { prop: true }.
Context for comments:
> { ["prop"]: true }
{ prop: true }
> { prop: true }
{ prop: true }

Can't access to variable inside a function arguments call [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 2 years ago.
case 'ADD_CHAT_MESSAGE':
const index = state.tasks.findIndex(elm => elm.userid === action.taskid)
const task = state.tasks
return update(
state, { tasks: { index: { $set: action.task } } })
I would like to use index inside update function but my IDE alerting me that index is declared nut never used.
Since index is dynamic, you must use [] with it, otherwise it will just be setting the index key
case 'ADD_CHAT_MESSAGE':
const index = state.tasks.findIndex(elm => elm.userid === action.taskid)
const task = state.tasks
return update(
state, { tasks: { [index]: { $set: action.task } } })

Object spread operator: Set property to be updated via payload [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 4 years ago.
Code snippet:
updateSelectedAreaColor: (state, payload) => {
state.selectedArea = { ...state.selectedArea, color: payload };
},
I'm updating the property color of the object state.selectedArea with a payload. Instead of hard-coding the property to be updated, I would like to set the property through my payload. For example:
updateSelectedAreaColor: (state, payload) => {
state.selectedArea = { ...state.selectedArea, payload.target: payload.value };
},
However, this code throws an error. Does anyone know how I can set the value to be updated via the payload?
Dynamic properties go into brackets:
updateSelectedAreaColor: (state, payload) => {
state.selectedArea = { ...state.selectedArea, [payload.target]: payload.value };
},
However I would prefer:
updateSelectedAreaColor: (state, payload) => {
state.selectedArea = { ...state.selectedArea, ...payload};
},
That way, you can easily change multiple props at the same time:
updateSelectedAreaColor(this.state, { color: "green", backgroundColor: "red" });

Updating object in array with Vuex [duplicate]

This question already has answers here:
Update data using vuex
(4 answers)
Closed 4 years ago.
How can I update an object inside an array with Vuex? I tried this, but it didn't work:
const state = {
categories: []
};
// mutations:
[mutationType.UPDATE_CATEGORY] (state, id, category) {
const record = state.categories.find(element => element.id === id);
state.categories[record] = category;
}
// actions:
updateCategory({commit}, id, category) {
categoriesApi.updateCategory(id, category).then((response) => {
commit(mutationType.UPDATE_CATEGORY, id, response);
router.push({name: 'categories'});
})
}
[mutationType.UPDATE_CATEGORY] (state, id, category) {
state.categories = [
...state.categories.filter(element => element.id !== id),
category
]
}
This works by replacing the 'categories' array with the original array without the matching element, and then concatenating the updated element to the end of the array.
One caveat to this method is that it destroys the order of the array, although in a lot of cases that won't be a problem. Just something to keep in mind.

Categories