Reducer :
function listPeopleByName (state = {
getPeopleName:{}
}, action){
switch(action.type){
case C.LIST_PEOPLE_NAME:{
return {
...state
,getPeopleName :action.payload
}
}
default : {}
}
return state
}
Action:
function listPeopleByName(config) {
return function (dispatch) {
ApiService(config)
.then((resp) => {
dispatch({
type: C.LIST_PEOPLE_NAME,
payload: resp.data,
});
})
.catch((error) => {
dispatch({
type: C.LIST_PEOPLE_NAME,
payload: error,
});
});
};
}
ApiService is a function that make an axios request and returns a respones
Dispatching code :
listPeopleByNameFunction = () => {
const listPeopleByNameParam = {
id: someone,
},
let data = {
PeopleId: "snjenfner",
};
let listPeopleByNameCategory = getApiConfig(
"POST",
listPeopleByNameParam,
data
);
this.props.listPeopleByName(listPeopleByNameCategory);
};
const mapDispatchToProps = (dispatch) => ({
listPeopleByName: (config) => dispatch(listPeopleByName(config)),
});
Although I take the previous state (...state) and change the state with the payload i'm getting, it still shows the state is mutated. I would have used reduxtoolkit but this is a way old project that doesn't need to be migrated to reduxtoolkit.
Related
On a React page, I have a method called goOut. This method calls upon a Redux action > Node controller > Redux reducer. I can confirm that the correct data values are returned inside the Redux action, the controller method, and the reducer. However, nonetheless, at point 1 below inside the goOut method, it returns undefined.
What am I doing wrong / how could it return undefined if the the reducer is returning the correct values? It is as if the await inside the goOut method is not working...
React page:
import { go_payment } from "../../appRedux/actions/paymentAction";
<button onClick={this.goOut}>
Button
</button>
async goOut(ev) {
try {
const data = { user: parseInt(this.state.userId, 10) };
let result = await this.props.go_payment({data});
console.log(result);
// 1. RETURNS UNDEFINED. As if it tries to execute this line before it has finished the previous line.
{
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(
{go_payment}, dispatch
);
};
Redux Action:
export const go_payment = (data) => {
let token = getAuthToken();
return (dispatch) => {
axios
.post(`${url}/goController`, data, { headers: { Authorization: `${token}` } })
.then((res) => {
if (res.status === 200) {
// console.log confirms correct data for res.data
return dispatch({ type: GO_SUCCESS, payload: res.data });
})
}
}
Node controller method:
Returns the correct data in json format.
Reducer:
export default function paymentReducer(state = initial_state, action) {
switch (action.type) {
case GO_SUCCESS:
// console.log confirms action.payload contains the correct data
return { ...state, goData: action.payload, couponData: "" };
}
}
I am trying to get my head around Redux. Doing something like TODO APP with React and Redux. I can add a new task, update its value, but I cannot delete the item correctly. I get an error Unhandled Rejection (TypeError): Cannot read property 'id' of undefined all the time. I pass the ID to the Delete function just like I do in the Update function. Server side works well. The fetch function itself works, and the delete of item from the database works, but an error occurs on the client side Help please guys
const initialState = {
list: [],
}
export default (state = initialState, action) => {
switch (action.type) {
case GET_TASKS: {
return { ...state, list: action.tasks }
}
case CREATE_TASK: {
return { ...state, list: [...state.list, action.task] }
}
case UPDATE_STATUS: {
return {
...state,
list: state.list.map((it) => {
return action.task.id === it.id ? action.task : it
}),
}
}
case DELETE_TASK: {
return {
list: state.list.map((it) => {
return action.task.id !== it.id ? action.task : it
}),
}
}
default:
return state
}
}
export function getTasks() {
return (dispatch) => {
fetch("/api/task")
.then((r) => r.json())
.then(({ data: tasks }) => {
dispatch({ type: GET_TASKS, tasks })
})
}
}
export function deleteTask(id) {
return (dispatch) => {
fetch(`/api/v1/task/${id}`, {
method: "DELETE",
})
.then((r) => r.json())
.then(({ data: task }) => {
dispatch({ type: DELETE_TASK, task })
})
}
}
My first question would be, in your deleteTask method what is being returned here? Does a delete method actually return the task you deleted?
.then(({ data: task }) => {
dispatch({ type: DELETE_TASK, task })
}
If not, another way you can address this is by changing the task in your dispatch to the id you are passing to the deleteTask method:
dispatch({ type: DELETE_TASK, id });
Then use the filter method instead of map in your reducer to return the tasks that don't match that deleted task's id, effectively "deleting" it from your state:
case DELETE_TASK: {
return {
list: state.list.filter((it) => {
return action.id !== it.id;
}),
}
}
i am configuring this reducer so that after creating a document on firestore, it would return the payload as the reducer state. i tried using redux thunk but i dont think im using it well because this code would remove the reducer from redux devtool extension.
switch (action.type) {
case "create-chatroom":
const room = action.payload.roomName;
return (dispatch) => {
const user = Auth.currentUser;
Db.collection("chatrooms")
.doc(action.payload.roomName)
.set({
authUsers: [user.uid],
messages: {
data: {
sender: "notification",
text: `${action.payload.roomName} has been created`,
timestamp: FieldValue.serverTimestamp(),
},
},
public: action.payload.public,
})
.then(() => {
dispatch({ type: "set-current-room", payload: room });
})
.catch((err) => {
dispatch({ type: "set-room", payload: state });
});
};
case "set-current-room":
return action.payload;
I am trying to get myLocation(redux state) variable which is used in next dispatch GET_POSTS_REQUEST. But when i tried to put await to get fully return value, it shows error.
index.js
const testFunc = () => {
const { myLocation} = useSelector(state => state.user);
dispatch({
type: MY_LOCATION_REQUEST,
data: {
lat: position.coords.latitude,
long: position.coords.longitude,
},
});
dispatch({
type: GET_POSTS_REQUEST,
data: {
dong: myLocation.dong,
},
});
};
sagas/location.js
function getLocationAPI(locationInfo) {
return axios.post('/location', locationInfo ,{withCredentials: true});
}
function* getLocation(action) {
try {
const result = yield call(getLocationAPI, action.data);
yield put({
type: GET_LOCATION_SUCCESS,
data: result.data,
});
} catch (e) {
yield put({
type: GET_LOCATION_FAILURE,
error: e,
});
}
}
function* watchGetLocation() {
yield takeLatest(GET_LOCATION_REQUEST, getLocation);
}
export default function* locationSaga() {
yield all([
fork(watchGetLocation),
]);
}
I have to use myLocation for next dispatch action in index.js. But, when i tried to put async/await to my dispatch, it didn't work. Is there any solution for this?
put method kinda dispatches too, for example this part
yield put({
type: GET_LOCATION_SUCCESS,
data: result.data,
});
you can always see as
dispatch({
type: GET_LOCATION_SUCCESS,
data: result.data,
});
So you have to "catch" this with reducer, for example
function yourReducer(state = initialState, action) {
switch (action.type) {
case GET_LOCATION_SUCCESS:
return Object.assign({}, state, {
user: Object.assign({},
state.user,
{
myLocation: action.data
}
]
})
default:
return state
}
}
And this will update your state with data returned from api call
So similar to some previous posts referenced below, I'm trying to chain dispatch through Thunk, however my difficulty is on the return from Sequelize. I can see the MySQL query hit the DB and return data, however that return is not flowing through the action-creator to the subsequent .then
I presume it's the manner in which I'm trying to use Sequelize - I'm new to it.
Many thanks!
Code:
initDB.js
...
export function sequelizeQry(qryName: string) {
let query;
// For later query mapping
switch (qryName) {
case 'POSummary':
query = qry.spPOLedgerCardSummaryALL;
break;
default:
query = qry.spPOLedgerCardSummaryALL;
}
return new sequelize.Promise(
() => sequelize.query(query, { type: sequelize.QueryTypes.RAW })
.then((response) => {
console.log('Returning promise: ', response); //<-- This hits the console with data
return response;
})
);
}
database-actions.js
// #flow
import { fetchingQuery } from '../action-creators/database-creators';
const fetchQuery = (qryName: string) =>
(dispatch: *) => dispatch(fetchingQuery(qryName));
export default fetchQuery;
database-creators.js
// #flow
// Action Types
import { FETCH_QUERY } from '../constants/ActionTypes';
import { sequelizeQry } from '../utils/initDB';
/** Action-creators */
export function fetchingQuery(qryName: string) {
const actionType = FETCH_QUERY;
return (dispatch: *) => {
dispatch({ type: `${actionType}_PENDING` });
sequelizeQry(qryName) //<-- This gets called
.then((payload) => dispatch({ //<-- Don't seem to get here
type: `${actionType}_FULFILLED`,
payload
}))
.catch(err =>
// Dispatch the error action with error information
dispatch({
type: `${actionType}_REJECTED`,
error: err
})
);
};
}
Some other references I've checked:
Redux thunk: return promise from dispatched action
return promise from store after redux thunk dispatch
All credit goes to adrice727.
Here's the code change for future visitors:
...
return new sequelize.Promise(
() => sequelize.query(query, { type: sequelize.QueryTypes.RAW })
.then((response) => {
console.log('Returning promise: ', response); //<-- This hits the console with data
return response;
})
);
...
// BECOMES
return new sequelize.Promise(
(resolve) => sequelize.query(query, { type: sequelize.QueryTypes.RAW })
.then((response) => {
console.log('Returning promise: ', response);
return resolve(response);
})
);