Redux saga pass multiple parameter as action and get it into saga function React native - react-native

i want to pass multiple parameters in Redux saga action so i did code as below
this.props.addCartData(_addToCartObject, 'guest')
inside dispatch i am passing like below
addCartData: (value, isFor) => dispatch(addCartRequest(value, isFor)),
in saga function I am accessing as below
function* callAddCart(data, isFor) {
try {
console.log("isFor--->", isFor);
}
}
export function* cartSaga() {
return yield all([
yield takeLatest(actionTypes.ADD_CART_REQUEST, callAddCart),
]);
}
But i log isFor I got undefined can you help me what i making wrong on this ?

it all works around your action creator addCartRequest,
let's say it returns an object like:
function addCartRequest(value, isFor) {
return {
type: actionTypes.ADD_CART_REQUEST,
value,
isFor
};
}
your saga watcher yield takeLatest(actionTypes.ADD_CART_REQUEST, callAddCart), will pass the whole object to callAddCart,
you can access their values assuming the first param as the whole object:
function callAddCart(action) {
console.log("actionType--->", action.type);
console.log("value--->", action.value);
console.log("isFor--->", action.isFor);
}
i created a working example in CodeSandbox:
https://codesandbox.io/s/2021-03-25-redux-saga-action-creator-payload-hk4sb?file=/src/App.js

Related

Vue & Jest - How to test a method with parameters? With vue/test-utils NOT jest-dom

After a lot of research I was finally able to test an method with the follow code
it('should call myFunction - on Desktop', async () => {
const mockMethod = jest.spyOn(myComponent.methods, 'myFunction')
const wrapper = shallowMount(
myComponent,
{
store,
localVue,
propsData,
stubs,
},
)
await wrapper.findAll('.container button-stub').at(0).trigger('click')
expect(mockMethod).toHaveBeenCalled()
})
And it worked :pray-pep:
But know I need to test an method passing an parameter and comparing the result.
This method changes my data, my data is like follows
data () {
return {
myOptions: [],
}
},
This method adds the argument, that is an number, in myOptions. That is what an want to test, call the function and compare if the parameter passed was added to myOptions
Sorry for my english and talks for the help
Assuming myFunction is the method you speak of, and it's called like this:
this.myFunction(123)
You could use Jest's toHaveBeenCalledWith() assertion to verify it was called with specific arguments, and then check the value of myOptions:
expect(mockMethod).toHaveBeenCalledWith(123)
expect(wrapper.vm.myOptions).toInclude(123)

How to retrieve data from a specific getters in vue?

How to retrieve data from a specific getters in vue?
this.$store.getters('client/list'))
TypeError: _this.$store.getters is not a function
at eval (Login2.vue?3936:64)
Step 1: Set the getter in the store.
getters: {
clientList: state => {
return state.clientList
}
}
Step 2: Call the getter in your component as computed
computed: {
clientList () {
return this.$store.getters.clientList
}
}
Check your syntax. The getter you posted won't work because you're missing the module-specific syntax.
As an example from the following link:
this.$store.getters['ModuleA/getCategory'](this.index)
See more here: Vue.js 2/Vuex - How to call getters from modules that has attribute namespaced:true without mapGetters?

Correct usage of getters in vuex

I'm currently developing an app with vue v2, and something got me thinking. It's kind of hard to find information for good practices so I decided I will ask here.
I have a laravel api and vue for front end. Until now my models were such that will hold only a few objects (< 100), so I just put the in the state, and get what ever needed with a getter. Now I have a model that will hold > 10000 objects, so putting them all into the state is pretty much out the topic. The way I solve this problem is a have with action that gets a single object from the api by id, and put it in the state, after a check if its not in there already. The check happens with a getter that I'm also using when I need this object. So I have similar structure:
​
// mutation
[mutation_types.FETCH_SOMETHING](state, {something}) {
if (!this.getters.getSomethingById(something.id)) {
state.somethings.push(something)
}
}
// action
const {data} = await axios.get('~route~')
commit(mutation_types.FETCH_SOMETHING, {something: data.something})
// getter
getSomethingById: state => id => {
return state.somethings.find(something => something.id === id)
}
​
So this is working, but there are 2 problems that I see. The first is every time when I need a something I should call the dispatch to get the item from the api into the state and then the getter to get the actual object and the second problem is the check is happening after the api call, so even if I have this specific something in the state, I'm doing a request for it.
A way to fix both of those problems that I though of calling the just working with the getter, which will check that state, if the searched ID is found in there it will be returned, if not, the dispatch will get it from the api and then return it.
I feel like I'm adding logic to the getter that doesn't belong there, but I can't think of another way to achieve this. Is there something that I'm missing / doing wrong somewhere?
Take advantage of the async nature of vuex actions and promises. Do the check for existence directly in the action along with the api call if needed:
state: {
items: []
}
mutations: {
addItem: (state, item) => {
state.items.push(item)
}
}
actions: {
fetchItem: async (context, id) => {
let item = context.state.items.find(i => i.id === id)
if (!item) {
item = await axios.get('/example/' + id).then(response => {
context.state.commit('addItem', response.data)
return response.data
})
}
return item
}
}

How to access the current instance in nuxt page validate()?

I return a Promise in validate(). Now, I want to pass the data which is returned in the validation by the server to one of the methods. However, I am not able to do this. Please help!
validate({ params, store, context }) {
return store.dispatch(types.VALIDATE_PARAMS_ASYNC, params.id).then(data => {
this.saveSettings(this, data)
return true
}).catch(e => {
return false
})
}
Its not possible. Validate executed before the instance initialized, so you cant access methods. And validate isnt supposed to be used that way.
For passing data to need either to save them into vuex store ( preferably in fetch method ) or return them as data in asyncData method. Then you can do what you want with your data in for example mounted method, or beforeMounted.

Return value from vuex mutation? (id for newly created object)

I'm trying to create an object in one part of vuex store, and then pass id to it to another object, and i'm not sure how to properly do that since mutations can't return returning anything (in this case, id).
Two store objects look like this:
// store/report.js
const state = {
name: 'Untitled Report',
subReportIds: []
};
// store/subReport.js
const state = { ... }
And i'd like this action to create blank report, then blank subreport, and then assign subreport id to newly created report. (subreports are independent entities, and can be used by multiple reports, hence different area in store)
const actions = {
createNewReport({ state, commit }) {
commit(mutationTypes.CREATE_NEW_REPORT)
// below doesn't work - i can't get return from mutation
let newSubreportId = commit(mutationTypes.ADD_NEW_SUBREPORT)
// if this worked, i'd then do something like
commit(mutationTypes.ADD_SUBREPORT_TO_REPORT, newSubreportId)
}
};
How can i achieve the above?
So best way to accomplish to me would be to dispatch actions instead of committing the mutations. If you look at the methods in Vuex source, commit only executes with no return (so is a void) and dispatch returns the value you return from the action (which is a function)
For my actions, i always return a promise so that i can compose them like you mention above. Here is an example.
fetchSomething ({ commit }) {
return mockApiGetIds()
.then(response => {
commit({
type: SOME_MUTATION,
ids: response
});
return response;
});
},
Disclaimer : I don't know if it is truely a good idea, but at least, it seems to work, and to me, it feels prettier than having to use actions and promises, or to generate the id in the action...
With your mutation, you can pass an argument. To return a value from a mutation (like a newly created id), I write it to a placeholder in that argument :
someMutation(state, arg){
//...
arg.out = {
status : "succeed"
}
}
//...
this.$store.commit('someMutation', arg);
if(arg.out !== "succeed") console.log("ERROR");