0

I am doing reactjs so I need to update a field in away that will trigger state change.

I have this payload(only show 1 but it is an array of many)

    [
                {
                    id: 1,
                    name: "Fridge2",
                    selected: true,
                    sharingId: 'ae9b9566-3b5c-4772-a0a1-07ed8b354b8f',
                    sharingWith: ["[email protected]", "[email protected]"],
                    storageItems: [
                        {
                            id: 'ae9b9564-3b5c-2711-a421-07ed8b354b8f',
                            name: 'Chicken Breats',
                            qty: 10,
                            expiresOn: '3',
                            category: 'Meat',
                            categoryId: 'BDEC0494-B16E-411B-8E32-A64A00E943F8',
                            unitType: 'Pieces',
                            unitTypeId: '63CDB076-C20D-4DC5-A181-A64A00E94409'
                        },
                        {
                            id: 'ae9b9566-3b5c-2711-a4a1-07ed8b354b8f',
                            name: 'Chicken Breats2',
                            qty: 10,
                            expiresOn: '0',
                            category: 'Meat',
                            categoryId: 'BDEC0494-B16E-411B-8E32-A64A00E943F8',
                            unitType: 'Pieces',
                            unitTypeId: '63CDB076-C20D-4DC5-A181-A64A00E94409'
                        },
                        {
                            id: 'ae9b9566-3b5c-2712-a0a1-07ed8b354b8f',
                            name: 'Chicken Breats3',
                            qty: 10,
                            expiresOn: '4',
                            category: 'Meat',
                            categoryId: 'BDEC0494-B16E-411B-8E32-A64A00E943F8',
                            unitType: 'Pieces',
                            unitTypeId: '63CDB076-C20D-4DC5-A181-A64A00E94409'
                        }
                    ]
                }
]

I want to find storageItem that matches the an ID 'ae9b9564-3b5c-2711-a421-07ed8b354b8f' (first one in the array)

I then want to take it out update the a field(say qty) stick it back in and have a state change happen.

This was my very bad 1st attemp at it. It does not work

case actions.STORAGE_ITEM_USED: {
            var foundItem = state.selectedStorage.storageItems.filter(i => i.id == action.payload);
            var newQty = foundItem[0].qty - 1;
            foundItem[0].qty = newQty;
            var nonChangedStorageItem = state.selectedStorage.storageItems.filter(i => i.id != action.payload);

            var allItems = nonChangedStorageItem.concat(foundItem);
            state.selectedStorage.storageItems = allItems;

            return {
                selectedStorage: state.selectedStorage,
            }

        }

Edit

I have this now but I see a new possible answer that I will checkout

var newSelectedStorage =  Object.assign({} , state.selectedStorage);

   var foundItem = newSelectedStorage.storageItems.filter(x => x.id == action.payload);
   foundItem[0].qty = foundItem[0].qty - 1;

   var nonChangedItems = newSelectedStorage.storageItems.filter(x => x.id != action.payload);

   newSelectedStorage.storageItems = nonChangedItems.concat(foundItem);

webpack.config.js

module.exports = {
  devtool: 'inline-source-map',
  entry: "./app/index.js",
  output: {
    path: __dirname + '/dist',
    filename: "bundle.js"
  },
  devServer: {
    contentBase: "./app",
    inline: true,
    port: 3333
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015', 'react']
        }
      },
      {
        test: /\.scss$/,
        loaders: ['style', 'css', 'sass']
      },
      {
        test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
        loader: 'url-loader'
      }
    ]
  },
   externals: {
    jquery: 'jQuery'
  },
} 
3
  • I believe the issue is that you are mutating the original object, then returning it. Redux expects a new object to completely overwrite the state. You might be able to get away with Object.assign-ing your existing state, mutating that, and returning it. Commented Aug 12, 2016 at 18:44
  • New Object for SelectedStorage I am guessing? Commented Aug 12, 2016 at 19:06
  • Redux state handlers return an entirely new state object, so the reference has to change. There are some shortcuts to make this really easy, using ES6's spread operators - Dan goes through it all in his Redux tutorials. Commented Aug 12, 2016 at 19:10

1 Answer 1

1

By the looks of it, you're trying to decrease the qty property on any matching objects in state.selectedStorage.storageItems.

Since Redux needs a whole new object, we can use ES6's object spread operators to return a new object with most of the values already filled in.

case actions.STORAGE_ITEM_USED:
    return {
        ...state,
        selectedStorage: state.selectedStorage.storageItems.map(i => {
            if (i.id != action.payload) return i;
            return {
                ...i,
                qty: i.qty - 1
            }
        })
    }

I can't test if this works, but the idea is that we are returning a new object, copying existing state objects, then overwriting selectedStorage with a new array where only items whose ids matching action.payload's qty properties are decreased.

Sign up to request clarification or add additional context in comments.

10 Comments

I am in process checking this out. On a side note what do I need to get "...state" to work? In Visual Studio code I get red underline under the 3 dots saying "properly assignment expected". Get same problem with ...i
state is your state object, which is the first argument in your reducer (action is the second argument). The three dots ... is part of ES6's destructuring and "rest" syntax. If you're working with React/Redux, you're likely using Babel, so by simply including the babel-preset-es2015 preset, it should transpile fine.
I do have babel-prset-es2015. I think this is an issue with Visual studio code. I used the 3 dots before for ...props with no problems but I get problems here Unexpected token (134:18) when I build it via webpack.
Hmm, a basic recreation works for me here on JSFiddle - is Babel set up as a loader for your .js files?
I will post my webpack.config but I think the issue is that Visual Studio Code ide is causing the problem.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.