Why the new value is not dispatched? - reactjs

I am trying to set new values by redux but a single key "status" every time after dispatching as an empty string. I don't know what is it and why every time empty maybe somebody know solution?
call action and dispatch code:
store.dispatch(actionSetNewResponseFilterValues({
active_level: "1",
query_in: ["0"],
status: ["15"]})
);
action method:
export const actionSetNewResponseFilterValues = (newValues) => {
return {
type: SET_RESP_FILT_VALS,
newValues
}
}
and code in reducer:
case SET_RESP_FILT_VALS:
case LOAD_RESP_FILT_VALS:
return {
...state,
filter: {
...state.filter,
newValues: {
...state.filter.newValues,
...action.newValues
}
}
}
#udpated
when in reducer coding whithout destructuring-assignment:
case SET_RESP_FILT_VALS:
case LOAD_RESP_FILT_VALS:
return {
...state,
filter: {
...state.filter,
newValues: action.newValues
}
}
in dispatching I see an empty status key:

Related

Unable to filter data in Redux Reducer

I'm trying to create a reducer for a ToDo App where i have successfully managed to create an Add reducer but somehow i'm unable to filter data on the basis of the ID suppose my ID is 1 then if there is a ToDo Bucket(bucket is basically a parent where i'm creating ToDo's) then get that ToDo bucket data.
In Redux dev tools i have checked it is showing me a infinite hierarchical tree of filteredData object. but not showing directly the Bucket ID 1 data and same with delete reducer as well. Can someone please help in highlighting what exactly wrong i'm doing or missing.
case EDIT_TODO_BUCKET: {
return (
{
...state,
data: {
...state.data,
[action.payload.id]: {
...state.data[action.payload.id],
filteredData: state.data[action.payload.id]
}
}
}
)
}
case DELETE_TODO_BUCKET: {
return (
{
...state,
data: {
...state.data,
[action.payload.id]: {
...state.data[action.payload.id],
}
}
}
)
}
case DELETE_TODO_BUCKET: {
return (
{
...state,
data: {
...state.data,
[action.payload.id]: {
...state.data[action.payload.id],
}
}
}
)
}
^ Read this It doesn't do anything at all except create a new reference each time.
I imagine you might want the following:
return {
...state,
// removes the key of action.payload.id from the state.data
data: Object.entries((acc,[key,value]) => key === action.payload.id ? acc : ({...acc,[key]:value}),{})
}

Composing a redux reducer for nested objects in an array

I'm new to Redux and am having some difficulty composing a working reducer for my situation.
My current state looks like this
export const userData = {
userID: '12345678',
userDetails: {
firstName: 'Joe',
surname: 'Bloggs'
},
currentGames: [
{
gameId: 'G-00000001',
gameSelections: [
{
subgameId: '',
selection: ''
}
]
}
]
};
My action looks like this
function selectWinner (gameId, subgameId, selection) {
return {
type: SELECT_WINNER,
gameId,
subgameId,
selection
}
}
The aim is to be able to add/update the objects in the gameSelections array.
There may be more than one Object in the currentGames array also.
I've heard I should use .map but I'm not really sure how.
You're on the right track for using .map() to iterate over the array of objects. It also looks like your action-creator has all the necessary parameters to update your reducer state.
Your reducer can look something like this:
const userReducer = (state=userData, action) => {
switch(action.type){
case SELECT_WINNER:
return {
...state,
currentGames: [...state.currentGames].map((game) => {
if(game.gameId == action.gameId){
return {
...game,
gameSelections: [...game.gameSelections].map((gameSelection) => {
if(gameSelection.subgameId == action.subgameId){
return {
...gameSelection,
selection: action.selection
}
} else {
return gameSelection
}
})
}
} else {
return game
}
})
}
default:
return state
}
}
Kind of messy, but would get the job-done with a deeply nested state.
Add item to array:
case'ADD_ITEM':
return {
...state,
some_arr: [...state.some_arr, action.payload]
}
update spicific item in array:
case 'UPDATE_ITEM':
return {
...state,
some_arr: state. some_arr.map(
(item, index) => index === specific_index
? {...item, ...action.payload}
: content
)
}
Deep cloning of the state is required.
useful link-https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns
const reducer = (state = userData, action) => {
switch (action.type) {
case CASENAME:
return {
userID: state.userID,
userDetails: {
...state.userdetails
},
currentGames: [
{
gameId: action.gameId,
gameSelections: [
{
subgameId: action.subgameId,
selection: action.selection
}
]
}
]
};
}
}

Redux state coming out to be undefined

I am having tough time figuring out why my redux state is coming out to be undefined on a later stage.
so I have an action which looks like this
export const coinUpdateState = (booleanValue) => {
console.log(typeof booleanValue) //This logs Boolean
return function (dispatch) {
dispatch({
type: COIN_UPDATE_STATE,
payload: booleanValue
})
}
}
and a reducer which looks like this
const initialState = {
DataFetching: true,
DataSucess: [],
DateError: [],
DateError: false,
DataSort: true,
DataUpdate: true
}
export default function(state = initialState, action) {
switch (action.type) {
case EXCHANGE_CURRENCY_FETCHING:
return {
DataFetching: true,
DataSort: true
}
case EXCHANGE_CURRENCY_FETCH_SUCCESS:
return {
...state,
DataSucess: action.payload,
DataFetching: false,
DataSort: false
}
case EXCHANGE_CURRENCY_FETCH_ERROR:
return {
...state,
DateError: action.payload,
DataFetching: true,
DateError: true,
DataSort: true
}
case COIN_UPDATE_STATE:
console.log(action.payload) //This logs the boolean value I am sending
return {
DataUpdate: action.payload
}
default:
return state
}
}
Later I am using it like this in my app
render () {
console.log(this.props.cryptoUpdateState)
if (this.props.cryptoUpdateState) {
console.log("Inside if render")
displayData = async () => {
this.coinURL = await AsyncStorage.getItem("CryptoCurrencySelected").catch((error) => {
console.log(error)
})
if (this.coinURL != "undefined" && this.coinURL != null) {
console.log("Inside Async", this.coinURL)
this.props.exchangeToDisplay(this.coinURL)
}
if (this.coinURL == null || this.coinURL == "undefined") {
console.log("Null", this.coinURL)
this.coinURL = "BTC"
}
}
displayData()
this.props.coinUpdateState(false)
}
In the above snippet notice the initial console.log, it logs true correctly the first time, there after it logs undefined in console when I am actually passing false (this.props.coinUpdateState(false)).
Also Notice the logs in my code, they are logging the value I am sending correctly everywhere besides in the later stage where it is logging undefined (in console.log).
Question: What could I be doing wrong here?
A reducer will return a new version of the state of your app. If you don't want to lose your previous state you will need to make sure you always return it with any additions/modifications you need.
Whatever is returned from the switch case that is triggered is going to be the next version of state, which for COIN_UPDATE_STATE is going to just have DataUpdate in.
Make sure all you are doing ...state for all your redux reducer actions in order to make sure you keep state.
e.g.
case COIN_UPDATE_STATE:
return {
...state,
DataUpdate: action.payload
}

Delete an element from array using redux

I am trying to make a todo app using redux and I'm stack on how to delete a todo from the array.
reducer.js
export default function todo(state, action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
case 'REMOVE_TODO':
return {
id: action.id,
...state.slice(id, 1)
}
default:
return state;
}
}
action.js
let nextTodoId = 0
export const addTodo = text => ({
type: 'ADD_TODO',
id: nextTodoId++,
text
})
export const removeTodo = id => {
type: 'REMOVE_TODO',
id
}
So far i can add and toggle a todo as completed or not. Thanks
Using redux you need to return all array elements except the removed one from reducer.
Personally, I prefer using the filter method of the Array. It'll return you a shallow copy of state array that matches particular condition.
case 'REMOVE_TODO':
return state.filter(({id}) => id !== action.id);
In react redux application, you should know, you always have to create a new object,
to deleting an item please use spread operator like this :
return [...state.filter(a=>a.id !== id)]

Updating state with nested array of objects

This is something also called as deep state update. Where I have to update nested state array.
I am implementing a simple redux application. Here I want to update the state which is nested array of object. My reducer function takes state, action. I have to update responses property of state with new value. I tried to map/iterate the state but it isnt working for me. Is there a way to update those specific values and return update state.
const sampleData = [{
"id": 1,
"text": "Hobby",
"answers": [{
"id": 1,
"text": "Chess",
"responses": 5
}]
}];
const action = {
type: "VOTE",
questionId: 1,
answerId: 3
};
This is handleSubmit function I am calling when Submit button is clicked on form.
handleSubmit(e){
const store = createStore(hobbyReducer, hobby); // created store here
var k = (document.querySelector('input[name = "hobby"]:checked').value);
store.dispatch({type:"SUBMIT", text: k, id: 1}); // Dispatching action to reducer
store.subscribe(()=>{
console.log(store.getState());
});
}
Here is reducer part of program:
function hobbyReducer(state, action) {
switch(action.type){
case "SUBMIT":
return{
...state,
answers: state.answers.map(e=> (e.text === action.text && e.answers.id === action.id)?
{ ...answers,
responses: (e.responses+1)} :
hobby )
}
break;
default:
return state;
}
}
initial state = sampleData; // Array object given above
I am unable to update the responses property which is in a nested array
This is the code I wanted to write, after some research I finally did what was required. Although this is not solution in terms of time complexity.
`
case "SUBMIT":
const updatedState = state.map(e =>{
if(e.id === action.id)
return{...e,
answers: e.answers.map(f =>{
if(f.text === action.text){
return{
...f,
...{responses: f.responses + 1},
}
}
return f;
})
}
return e;
})
console.log("updatedstate", updatedState)
return updatedState
Just an error in your map I think:
function hobbyReducer(state, action) {
switch(action.type) {
case "SUBMIT":
return {
...state,
answers: state.answers.map(answer => {
if (answer.text === action.text && answer.id === action.id) {
answer.response = answer.response + 1;
}
return answer;
});
}
default:
return state;
}
}

Resources