1

I dont know how to add to the new array individually using the key of the element. I have state set up here with a function to the new array onclick:

this.state = {
  applications: [
    {
      id: 1,
      name: "John Smith",
      position: "Server",
      applied: "03/15/16",
      experience: 2,
      availability: {
        M: 2,
        T: 2,
        W: 1,
        Th: 2,
        F: 1,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Have you ever been convicted of a felony?",
          answer: "No"
        }
      ]
    },
    {
      id: 2,
      name: "Jane Smith",
      position: "Cook",
      applied: "02/08/16",
      experience: 4,
      availability: {
        M: 1,
        T: 1,
        W: 1,
        Th: 1,
        F: 0,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Have you ever been convicted of a felony?",
          answer: "Yes"
        }
      ]
    },
    {
      id: 3,
      name: "David Jessup",
      position: "Chef",
      applied: "03/08/16",
      experience: 2,
      availability: {
        M: 2,
        T: 2,
        W: 2,
        Th: 2,
        F: 2,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Are you authorized to work in the United States?",
          answer: "Yes"
        }
      ]
    },
    {
      id: 4,
      name: "Clay vanSchalkwijk",
      position: "Cook",
      applied: "03/08/16",
      experience: 1,
      availability: {
        M: 1,
        T: 0,
        W: 1,
        Th: 0,
        F: 1,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Are you authorized to work in the United States?",
          answer: "Yes"
        }
      ]
    }
  ],
  saved: []
};

This is the function I want to run:

onFavorite = savedApp =>
  this.setState({
    saved: [...this.state.saved, savedApp]
  });

Here I want to click favourite then have it run the function and add to the new array (by the key ID):

render() {
  const all_applications = this.state.applications.map(function(elem) {
    return (
      <li key={elem.id}>
        {" "}
        <h1>{elem.name}</h1>
        <p />
      </li>
    );
  });
  return (
    <div className="App">
      <Header />
      {all_applications}
      <button onClick={this.onFavorite}>Favorite</button>
    </div>
  );
}
4
  • Hello, welcome to SO. You should explain what error you get if you want people to help you in an effective way. Commented Sep 17, 2018 at 22:34
  • So you want a a "Favourite" button for each applicant? Commented Sep 17, 2018 at 22:58
  • @DacreDenny yes Commented Sep 17, 2018 at 22:59
  • @JRUtily I am not getting any errors, I just dont know how to add it by the id(one-by-one) Commented Sep 17, 2018 at 22:59

2 Answers 2

1

Here is a slightly different approach with a separate Application component. onFavorite method adds only the ids to the saved state. If the id is already there, it removes. renderFavs method maps the saved state then grab the related applications from the state.

class App extends React.Component {
  state = {
    applications: [
      {
        id: 1,
        name: "John Smith",
        position: "Server",
        applied: "03/15/16",
        experience: 2,
        availability: {
          M: 2,
          T: 2,
          W: 1,
          Th: 2,
          F: 1,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Have you ever been convicted of a felony?",
            answer: "No"
          }
        ]
      },
      {
        id: 2,
        name: "Jane Smith",
        position: "Cook",
        applied: "02/08/16",
        experience: 4,
        availability: {
          M: 1,
          T: 1,
          W: 1,
          Th: 1,
          F: 0,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Have you ever been convicted of a felony?",
            answer: "Yes"
          }
        ]
      },
      {
        id: 3,
        name: "David Jessup",
        position: "Chef",
        applied: "03/08/16",
        experience: 2,
        availability: {
          M: 2,
          T: 2,
          W: 2,
          Th: 2,
          F: 2,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Are you authorized to work in the United States?",
            answer: "Yes"
          }
        ]
      },
      {
        id: 4,
        name: "Clay vanSchalkwijk",
        position: "Cook",
        applied: "03/08/16",
        experience: 1,
        availability: {
          M: 1,
          T: 0,
          W: 1,
          Th: 0,
          F: 1,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Are you authorized to work in the United States?",
            answer: "Yes"
          }
        ]
      }
    ],
    saved: []
  };

  onFavorite = app => {
    const { saved } = this.state;
    const check = saved.includes(app.id);
    if (check) {
      const newSaved = saved.filter(fav => fav !== app.id);
      return this.setState({ saved: newSaved });
    }
    this.setState(currentState => ({
      saved: [...currentState.saved, app.id]
    }));
  };

  renderApplications() {
    const { applications } = this.state;
    return applications.map(app => (
      <Application key={app.id} app={app} onFavorite={this.onFavorite} />
    ));
  }

  renderFavs() {
    const { saved, applications } = this.state;
    const saveds = saved.map(id => applications.find(app => app.id === id));
    return saveds.map(fav => <p key={fav.id}>{fav.name}</p>);
  }

  render() {
    return (
      <div>
        <ul>{this.renderApplications()}</ul>
        <h3>Favorites</h3>
        {this.renderFavs()}
      </div>
    );
  }
}

const Application = props => {
  const { app, onFavorite } = props;
  const handleFavorite = () => onFavorite(app);

  return <li onClick={handleFavorite}>{app.name}</li>;
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

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

Comments

0

If I understand your question correctly, then you can render a "Favourite" button for each applicant, by making the following adjustment to your render() function:

render() {
    const all_applications = this.state.applications.map((elem) => {
      return(
        <li key={elem.id}> <h1>{elem.name}</h1>
          <p></p>
          { /* Render a favourite button for each 'elem' applicant. 
               Pass the elem/applicant data to the onFavorite method like so:
            */  }
          <button onClick={ () => this.onFavorite(elem) }>Favorite</button>
        </li>
      )
    })
    return (
      <div className="App">
      <Header />
      {all_applications}
      </div>
    );
  }
}

4 Comments

I am getting an cannot read property of "onFavorite" of undefined error
@Berheet sorry about that , please see update above where you will need to use .map((elem) => { syntax - does this work for you?
that was right to get rid off error! But what would the function look like to add it to the array? right now i have: onFavorite = () => { return( this.setState({ saved:[...this.state.saved, savedApp]}) )}
If you want to update onFavourite in that way, this should be possible: onFavorite = () => { this.setState({ saved:[...this.state.saved, savedApp]}) } Would you like me to update the answer?

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.