Redux update object with multiple params - javascript

Hello i have my reducers like this
case UPDATE_USER: {
return {
...state,
...action.newDataUser,
}
}
My object user is :
{
name: 'azerty',
email: 'azerty#yopmail.com',
birthday: '1990'
}
I have an action to update my user object :
export function updateUser(newDataUser) {
return { type: UPDATE_USER, newDataUser }
}
How to modify my reducers UPDATE_USER to update user object with multiple properties :
{
name: 'azerty updated',
email: 'azerty#yopmail.com updated',
}
Thanks

You can manually update required properties
case UPDATE_USER: {
let user = action.newDataUser;
['name', 'email', 'birthday'].forEach(key => {
user[key] = `${user[key]} updated`;
});
return {
...state,
...user,
}
}

Related

How use a mutation function in a action function in Vuex?

I have this Vuex:
export default new Vuex.Store({
state: {
userInfo: {
nit_ID: { ID: '', Desc: '' },
userName: { ID: '', Desc: '' },
typeDocument: { ID: '', Desc: '' },
document: '',
},
globalPublicKey: 'ASDFGHJKL1234567890',
},
mutations: {
updateUserInfo(state, payload) {
state.userInfo = payload;
},
},
getters: {
userInfo: (state) => { return state.userInfo; },
},
actions: {
validateUserSession(context) {
var valido = false;
try {
let storageInfo = JSON.parse(
sjcl.decrypt(context.state.globalPublicKey, localStorage.userInfo)
);
if (localStorage.userToken === storageInfo.token) {
context.mutations.updateUserInfo(storageInfo);
valido = true;
}
} catch (e) {
console.error(e);
}
return valido;
},
},
})
But the problem is that I can't access to the mutation updateUserInfo(), I know that is easy to solved, only do the updateUserInfo process in my action, but the question is How can I use a mutation into a action?
In VueJS you can call a mutation from an action by calling context.commit, like this:
context.commit('mutationName', params)
params can be omitted if not parameters are passed to the mutation.
More on this here: vuex.vuejs.org/guide/actions.html
Actually you call a mutation from anywhere with a commit - but it's advised to use actions (so dispatch an action) that in turn commits the data (actually mutates the state).

how to Modify a child object from you state in the reducer with Redux

I have a state with multiple objects inside it. Right now I can modify all the elements from the first level, like the step property. But I want to know how to modify the elements from an object inside of my state.
Initial state
const initialState = {
step : 1,
user: {
identification : {
email: '',
username: '',
},
localization: {
address: '',
country: '',
}}
My payload is this object:
identification : {
email: "some#html.com"
username: "s032190" }
And my rootReducer is this:
function rootReducer(state = initialState, action) {
switch (action.type) {
case ADD_USER:
return { ...state, user: action.payload }
case CHANGE_STEP:
return { ...state, step: action.payload }
case ADD_FIELD:
Object.keys(state.altaUsuario).forEach (cat => {
return { ...state.user, [cat] : action.payload}
})
default:
return state
}
};
Is it fine to use a loop? I tried with the map or the foreach, nothing works.
I also tried to call property in the spread operator, something like this:
return { ...state, altaUsuario[cat] : action.payload}
But it gives me a syntax error.
I can also modify the payload if is necessary.
Any idea??
You can try something like this
return { ...state,user : {...state.user ,identification :action.payload }}
if your action.payload is
{
identification : {
email: "some#html.com"
username: "s032190"
}
}
you have to override the identification property
return { ...state, user: { ...state.user, identification: action.payload.identification}

vue how set default props for nested object

my props is like this
house = {
kitchen:{
sink: ''
}
}
I tried something like this, didnt work.
props: {
house: {
type: Object,
default: () => {
kitchen : {
sink: ''
}
}
}
},
How to set default props for such object?
From the docs:
Object or array defaults must be returned from a factory function
So the problem is that you are not returning the default object.So you can either do:
props: {
house: {
type: Object,
default: () => ({ // <= note the parenthesis
kitchen : {
sink: ''
}
}) // <= here also
}
},
Or
props: {
house: {
type: Object,
default: () => {
return {
kitchen : { // <= note the return
sink: ''
}
}
}
}
},
The following solution should work :
props: {
house: {
type: Object,
default: () => ({
kitchen: {
sink:''
}
})
},
}
check this codesandbox
if the above solution doesn't work, you could use a normalized computed property :
props: {
house: { type: Object }
},
computed: {
normalizedHouse() {
return {
kitchen:{
sink: ''
}
}
}
}

Handle state update object

I am using redux for my application's state but I find it hard to update the state correctly when it is nested.
As you can see I use the ...state in my reducer but is there a way to use this when I only need to update a key of a child object and keep the rest of the state ? See below for example
// initial state
state = {
isFetching: true,
isUpdating: false,
content: {
key: 'content',
otherkey: 'content' // Keep this one
}
}
// returned new state
{
...state,
content: {
key: 'thing I only want to update'
}
}
Actions
export function requestUser() {
return {
type: REQUEST_USER
};
}
export function receiveUser(data) {
return {
type: RECEIVE_USER,
payload: data
};
}
export function fetchUser(userhash) {
return function (dispatch) {
dispatch(requestUser);
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
const data = {
status: 200,
data: {
firstName: 'Neal',
lastName: 'Van der Valk',
email: 'email#outlook.com',
hash: 'zea7744e47747851',
permissions: {
'admin': true,
'results': true,
'database': true,
'download': true,
'property': true,
'departments': true,
'users': true,
'devices': true,
'integrations': true,
},
notifications: {
'daily': true,
'weekly': false
}
}
};
dispatch(receiveUser(data));
});
};
}
Reducer
const INITIAL_STATE = {
isFetching: true,
isUpdating: false,
content: null
};
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case REQUEST_USER:
return {
...state,
isFetching: true
};
case RECEIVE_USER:
return {
...state,
isFetching: false,
content: action.payload.data
};
You can try Object.assign()
This example shows the usage.
{
...state,
content: Object.assign({}, state.content, {
key: 'thing I only want to update'
}
}
You can also use the same spread operator ...
var state = {
isFetching: true,
isUpdating: false,
content: {
key: 'content',
otherkey: 'content' // Keep this one
}
};
var newState = {
...state,
content: {
...state.content,
key: 'thing I only want to update'
}
}
console.log(newState);
In your initial state, content should be {} instead of null.
Then you can change the state in your reducer with Object.assign.
example :
case RECEIVE_USER:
return{
...state,
content: Object.assign({}, state.content, {
key: 'thing I only want to update'
}

Field args rejected when return a function not object

I want ask about GraphQL
This code will be failed, and shows error
Error: Mutation.addUser args must be an object with argument names as keys.
here is the code
const Schema = new GraphQLObjectType({
name: "Mutation",
description: "Mutation schema",
fields() {
return {
// Add user
addUser: {
type: UserSchema,
args: () => {
return {
firstName: {
type: GraphQLString
}
};
},
resolve(_, args){
return Db.models.user.update( () => {
return _.mapValues(args, (v, k) => {
return args[k];
});
}, {
returning: true
});
}
}
};
}
});
But, this code work perfectly
const Schema = new GraphQLObjectType({
name: "Mutation",
description: "Mutation schema",
fields() {
return {
// Add user
addUser: {
type: UserSchema,
args: {
firstName: {
type: GraphQLString
},
lastName: {
type: GraphQLString
}
},
resolve(_, args){
return Db.models.user.update( () => {
return _.mapValues(args, (v, k) => {
return args[k];
});
}, {
returning: true
});
}
}
};
}
});
Why args can't return object from function?
The fields itself can be a function, so having another function inside it to define args is kind of redundant.
The purpose of having them as functions is to be able to define types that need to refer to each other, or types that need to refer to themselves in a field.
So having only fields as a function will do the trick.

Categories

Resources