-1

I would like to write a function that after receiving an item in which I want to change a certain value, changes it and then updates the filters. I do not know how I have to get to this particular element in my object filters, because I pass the object itself, without any "id"

mapActions.js

export const setFilters = (el, old_filters) => {
    console.log(el)
    const filters = {
        ...old_filters,
        [el]: { 
          ...old_filters[el],
          active: !old_filters[el].active
        }
      };
    return (dispatch, getState) => {
        dispatch({
            type: actions.SET_FILTERS,
            filters: filters
        })
    }
}

FilersObject.js

    changeFilterHandler = (el, i) => {
        this.props.setFilters(el, this.props.filters);
    }

[..]

            {Object.keys(this.props.filters).map(x => this.props.filters[x]).map((el, i)=> {
                return(
                    <ObjectFiltersElement 
                        key={i} 
                        object={el}
                        changeFilterHandler={(el) => (this.changeFilterHandler(el))}
                        />
                )
            })}

Everything works, but simply I don't know how in mapActions.js in function setFilters() swap suitable object after changes variabe 'active'

The console.log(el) : enter image description here

and the error I got :

TypeError: Cannot read property 'active' of undefined

State :

const initState = {
    filters: {
        basen: {
            active: true,
            name: 'BASEN'
        },
        koszykowka: {
            active: true,
            name: 'KOSZYKÓWKA'
        },
        pilka_nozna: {
            active: true,
            name: 'PIŁKA NOŻNA'
        }
    }}
poldeeek
  • 313
  • 2
  • 16
  • It looks silmilar but no. I have problem because my function can not recognize object which is changing in 'filters' object. I know how to change it, but don't know how to tell my function which one it should be. I edited a little my ask now. Maybe it will be better to understand problem. – poldeeek May 06 '20 at 23:55
  • At that point, you should provide a [mcve]. And remember not to include the answers into your question thus invalidating them. – Emile Bergeron May 07 '20 at 00:00
  • 1
    Yea, I know. Sorry for that, I am still learning how to use this forum. But your answer helped anyway so thanks :P – poldeeek May 07 '20 at 00:04

1 Answers1

3

Your current code appears to mutate your old_filters in setFilters. Instead, make sure to only change the new object you create.

The following is a fairly common pattern to shallow copy down your state tree to the point of where you need to change a variable.

export const setFilters = (el, old_filters) => {
  const filters = {
    ...old_filters,
    [el]: { 
      ...old_filters[el],
      active: !old_filters[el].active
    }
  };

  return (dispatch, getState) => {
    dispatch({
      type: actions.SET_FILTERS,
      filters: filters
    })
  }
}

Edit: It would be beneficial to pass your filter key rather than the object value to your change handler:

{Object.entries(this.props.filters).map(([key, el])=> {
  return(
    <ObjectFiltersElement 
      key={key} 
      object={el}
      changeFilterHandler={() => (this.changeFilterHandler(key))}
    />
  )
})}
Nick
  • 16,066
  • 3
  • 16
  • 32
  • I tried that, but I got TypeError: Cannot read property 'active' of undefined – poldeeek May 06 '20 at 23:48
  • I added the console.log(el) screen. setFilters function has got the content of 'el' but I think that this function can not recognize it in filers object. And I don't know how to fix it. – poldeeek May 06 '20 at 23:52
  • @poldeeek use `[el.name]` instead. – Emile Bergeron May 06 '20 at 23:57
  • I can't because of my initState in redux I think. I added state just now. – poldeeek May 06 '20 at 23:58
  • Okay, I get the structure. I'm going to make a recommendation to how you're calling the change handler – Nick May 07 '20 at 00:01
  • @poldeeek see if this works for you. Instead of passing objects, just pass the right key to the change handler. – Nick May 07 '20 at 00:04
  • I made changed but still didn't work. https://codesandbox.io/s/immutable-dream-4xk06?file=/src/objectFiltersElement.js - i putted code here. The error I got - TypeError: Cannot read property '#' of undefined - . In console log from setFilters from mapActions.js key value is as undefinded. – poldeeek May 07 '20 at 00:11
  • Ok i fixed it a little. But now I got an error Uncaught TypeError: Cannot read property 'basen' of undefined – poldeeek May 07 '20 at 00:19
  • Happy to keep troubleshooting but I'll need a working example – Nick May 07 '20 at 00:19
  • I putted my current code and photo of console.log() - https://codesandbox.io/s/immutable-dream-4xk06?file=/public/index.html -. I don't know how to put all this code with redux etc. on codesandbox... – poldeeek May 07 '20 at 00:28
  • The error is about this lane : " [key]: { " – poldeeek May 07 '20 at 00:31
  • Even when I try console.log(old_filters[key]), I got error : Cannot read property 'basen' of undefined – poldeeek May 07 '20 at 00:35
  • Yeah, I mean it seems to think `old_filters` is undefined. Can you figure out why that might be? – Nick May 07 '20 at 00:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213287/discussion-between-poldeeek-and-nick). – poldeeek May 07 '20 at 00:42