score:5

Accepted answer

Cannot read property 'saved' of undefined

You are not correctly referencing this.state for saved or headline.

Cannot read property 'state' of undefined

Either add a constructor and bind this to your saved function.

constructor(props) {
  super(props);
  this.saved = this.saved.bind(this);
}

saved() {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}

Or define saved as an arrow function to bind this

saved = () => {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}

Should be

saved() {
  const { headline, saved } = this.state;
  this.setState({ saved: [...saved, headline] });
}

or

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

UPDATE: Save a specific post/headline

I see now, if you wish to save a specific headline then you need to update the signature of your saved function and how you call it.

saved = headline => {
  this.setState(
    prevState => ({ saved: [...prevState.saved, headline] })
  );
}

and when you invoke it as a callback

<button
  className="btn-primary btn mt-2 mb-4"
  onClick={() => this.saved(post)} // pass the current post defined in the map callback
>
  Add this article
</button>

One minor comment about naming, consistently referencing the same "object" the same way throughout code goes a long way in helping readability. I.E. how you reference headlines, posts, and articles. Pick one and be consistent.

this.state.headlines => this.state.headlines.map(headline => ...

this.state.posts => this.state.posts.map(post => ...

this.state.articles => this.state.articles.map(article => ...

score:2

    saved() {
        this.saved.push(this.headline);
        //alert('this is saved kind of');
    }

You cannot defined class methods like this without writing a constructor like this:

class NewsHero extends Component {
  constructor(props){
    super(props)
    this.saved = this.saved.bind(this)

  }

...the rest of everything you wrote

}

Without doing this, your saved function is not bound to the instance of the class. Its silly, yes, but that's how class methods work in javasript. The other option is to use an arrow function, which preserves the context if this:

    saved = () => {
        this.saved.push(this.headline);
        //alert('this is saved kind of');
    }

I think this is faster and cleaner, and its pretty commonly used.

That is problem 1. Problem 2 is that it appears you are trying to modify the state object directly when writing this.saved.push(this.headline). That's not how to do it. To modify your state, you need to use the this.setState function:

saved = () => {
  this.setState({
    saved: whatever you want this to be
  })
}

But it looks like you are already setting your state correctly in your fetch call, so I'm not sure what you're trying to accomplish with your saved function...?


Related Query

More Query from same tag