I need to access store in headlessJS in react native to dispatch an action.
I tried
AppRegistry.registerHeadlessTask('didEnterRegion', (beacon) => Util.didEnterRegion.bind(beacon, store));
and in Util.js
const didEnterRegion = async (beacons, store) => {
console.log(beacons);
store.dispatch({
type: FOUND_PLACES_FAIL,
payload: err
});
});
but now I receive the beacons object as an empty object. How do I pass that object too along with the store.
Sorry, so stupid of me.
I just had to pass the params in headlessJS.
AppRegistry.registerHeadlessTask('didEnterRegion', (beacon) => Util.didEnterRegion.bind(beacon, store));
const didEnterRegion = async (store, beacon) => {
console.log(beacon);
store.dispatch({
type: FOUND_PLACES_FAIL,
payload: err
});
});
Related
I'm trying to make a post request inside a function whenever i click on a button.
here is the code of the button
<Button onClick={handleClick}>Add to Cart</Button>
and here is the `handleClick funcion:
const handleClick = (event) => {
event.preventDefault();
props.postCart(itemData.product_name, itemData.product_price);
}
and here i showcase the code of mapDispatchToProps function:
const mapDispatchToProps = dispatch => {
return {
postCart: (productName, productPrice) => dispatch(postAddToCart(productName, productPrice))
}
}
finally the code of postAddToCart:
export const postAddToCart = (productName, productPrice) => {
const email = sessionStorage.getItem('email');
return (dispatch) => {
dispatch(productName, productPrice);
//REST API endpoint
axios.post('http://localhost:8000/api/auth/add-to-cart', {
email:email,
})
.then(resp => {
dispatch({
type: actionTypes.ADDED_TO_CART,
status: resp.status
});
})
.catch(resp => {
dispatch({
type: actionTypes.ADDED_TO_CART,
status: "FAILED"
});
})
}
}
But whenever i click the button Add to cart i get the following error:
Error: Actions must be plain objects. Use custom middleware for async actions.
knowing that i'm using the redux-thunk middleware.
Can you please tell me what's the problem and how can i fix it ? thank you ^^. if i missed something tell me in comments to add it ^^
Your function postAddToCart() returns a "dispatcher", i.e. a function that expects dispatch as an argument.
The error is that you are trying to dispatch this "dispatcher", instead of an "action":
// wrong: calling 'dispatch()'
postCart: (productName, productPrice) => dispatch(postAddToCart( ... ))
// correct: calling the returned dispatcher and pass 'dispatch' as argument
postCart: (productName, productPrice) => postAddToCart( ... )(dispatch)
When calling a Vuex Action where Firebase successfully updates, followed by a Vuex Mutation on state.profile, Vue triggers the following errors upon save within watch().
[Vue warn]: Unhandled error during execution of watcher callback
Error: [vuex] do not mutate vuex store state outside mutation handlers.
I have cloned and then merged store.state.profile into formData via rfdc.
Form values are updated within it's own reactive() data object formData, versus immediately committing to store in order to later provide both save() and cancel() options.
template
<template>
<element-textarea
id="about"
title="About"
:rows="10"
v-model="about"
></element-textarea>
<element-checkbox
v-for="(specialty, i) in jSpecialties"
:key="i"
:id="specialty.toLowerCase()"
:title="specialty"
v-model="specialties[specialty]"
>
{{ specialty }}
</element-checkbox>
</template>
script
...
const clone = require('rfdc/default')
export default defineComponent({
...
setup(){
...
let specialties: { [key: string]: boolean } = {}
jSpecialties.map(name => (specialties[name] = false))
const formData = reactive({
about: '',
specialties
})
watch(
() => store.state.profile,
() => {
try {
Object.assign(formData, clone(store.state.profile))
} catch (err) {
console.log('Error Appears Here', err)
}
}
)
const save = () =>
store.dispatch('updateProfile', formData)
.catch(err => console.log(err))
return { ...toRefs(formData), save }
}
})
vuex
export default createStore({
strict: true,
state: {
profile: {}
},
mutations: {
setProfile: (state, payload) => state.profile = payload,
},
actions: {
updateProfile: ({state, commit}, data) => {
const update = () =>
db
.collection(...)
.doc(...)
.set(data, {merge: true})
.then(_ => commit('setProfile', data))
.catch(err => console.log(err))
return update()
}
}
})
When removing strict: true from vuex, I receive this error:
Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.
Replacing watch() with watchEffect() get rid of the Maximum recursive updates exceeded error.
watchEffect(() => {
try {
Object.assign(formData, clone(store.state.profile))
} catch (error) {
console.log(error)
}
})
However, when updating Vuex with strict: true, I am still receiving the following:
Error: [vuex] do not mutate vuex store state outside mutation handlers.
I've discovered the issue. I overlooked my copying of a reference object back to state.
I needed to clone formData prior to dispatching, as the same data object was also committed to store via actions.
const save = () =>
store.dispatch('updateProfile', clone(formData))
.catch(err => console.log(err))
I am learning how to create Unsubscribe() using store.subscribe() method.
Below is the code. I don't understand the logic: why we use store.subscribe method to declare unsubscribe constant as an unsubscribe function for the store. (literally, subscribe should subscribe 'something' for the store, right?)
import store from './store';
const unsubscribe = store.subscribe(
() => console.log("Store changed!", store.getState())
);
store.dispatch({
type: "bugAdded",
payload: {
description: "Bug1"
}
});
unsubscribe();
store.dispatch({
type: "bugRemoved",
payload: {
id: 1
}
});
Also, please look at the following modified code: even only declare the constant unsubscribe, the console still executes the store.subscribe method.
import store from './store';
const unsubscribe = store.subscribe(
() => console.log("Store changed!", store.getState())
);
store.dispatch({
type: "bugAdded",
payload: {
description: "Bug1"
}
});
// unsubscribe();
store.dispatch({
type: "bugRemoved",
payload: {
id: 1
}
});
the above code has the same output as the following code (confused, anyone could explain)
import store from './store';
store.subscribe(
() => console.log("Store changed!", store.getState())
);
store.dispatch({
type: "bugAdded",
payload: {
description: "Bug1"
}
});
store.dispatch({
type: "bugRemoved",
payload: {
id: 1
}
});
store.subscribe will just create a suscription to our store, it will be listening the store and waiting for it to change, every time the store changes it will execute the callback we passed to it. When we subscribe to the store, it returns a function to unregister that subscription later that we can call whenever we need.
You could read more about it on the redux documentation
I built an input interface in React and stored the data in a Redux state.
Then, I created a new action for a Post API call. If the "data" parameter is a constant (that I created as a test), everything works fine.
In reality, I'd like to use a key from the Redux state as the data parameter.
In the example, I'm getting an error because props are not defined.
Does it makes sense to connect this action to the state? If yes, how to do it? Thanks a lot!
import axios from 'axios';
export const show_query_action = () => {
return dispatch => {
dispatch(show_query_started_action());
axios({
method: 'post',
url:'http://127.0.0.1:5000/show_query',
data: this.props.reducer_components
})
.then(res => {
dispatch(show_query_success_action(res));
})
.catch(err => {
dispatch(show_query_failure_action(err.message));
});
};
};
const show_query_started_action = () => ({
type: 'ADD_SHOW_QUERY_STARTED'
});
const show_query_success_action = todo => ({
type: 'ADD_SHOW_QUERY_SUCCESS',
payload: {
...todo
}
});
const show_query_failure_action = error => ({
type: 'ADD_SHOW_QUERY_FAILURE',
payload: {
error
}
});
If it needs to be callable with different parameters from a React component you can put the data parameter as a parameter to your action creator:
export const show_query_action = (data) => {
return dispatch => {
dispatch(show_query_started_action());
axios({
method: 'post',
url:'http://127.0.0.1:5000/show_query',
data: data
})
This is also easily testable. If you only call this action with parameters from the redux store, you can use the second parameter from redux-thunk (wich i presume you are using here):
export const show_query_action = () => {
return (dispatch, getState) => {
const data = getState().data; -> you would specify in wich part of the state your data lives, this is just an example
dispatch(show_query_started_action());
axios({
method: 'post',
url:'http://127.0.0.1:5000/show_query',
data: data
})
Hope this helps.
export function editPost(props){
const request = axios.put(`http://www.example.com/posts`, props) ;
return{
type: EDIT_POST,
payload: request
};
}
hi,, is this what a proper "Update" action should look like in Redux?
using axios to make the request
the type was created in another file and then imported
Thanks
axios is promise-based, so currently you're returning a payload that doesn't exist. Look for redux-thunk and use it in the following way:
actionCreator() {
return (dispatch) => {
return axios.put('url').then((res) => dispatch({ type: EDIT_POST, payload: res }))
}
}