Getting error with toFixed() method

Well, this seems like a very basic thing but I can’t see why the method is failing. I have an object with some props, for the sake of the argument let’s say this is my object:

myObj = {
 status: "Released",
 tagline: "The world has enough Superheroes.",
 title: "Venom",
 video: false,
 vote_average: 6.6,
 vote_count: 1701,
}

I am trying to use the toFixed() method in the vote_average property to always show in the user interface a whole number and a decimal, in case that the object only has a whole number. An example:

newObj {
 vote_average: 5
}

newObj.vote_average.toFixed(1) // expected output: 5.0

In my React component this isn’t working… The weird thing is that in another component it worked.

class Dashboard extends Component = {
 state = {
    movie: [],
    genres: []
  };

  async componentDidMount() {
    const queryString = `${apiUrl}${this.props.match.params.id}?api_key=${key}`;

    const { data: movie } = await http.get(queryString);
    const genres = movie.genres;

    this.setState({ movie, genres });
  }

 render() {
  console.log(this.state.movie.vote_average.toFixed(1))
 }
}

The above will throw an error, if I remove the toFixed() method the output is as expected.

edit: by the way, I’ve been having errors trying to accessing objects properties with dot notation in React in some scenarios, not sure why this happens.

What error are you getting?

The problem is not the method toFixed, you are calling it in a undefined object. Make sure this.state.movie.vote_average is set.

Since componendDidMount is async, you must know that render is called before you set the state in componentDidMount, which means vote_average will be undefined.

1 Like

I suspected that, but I am not sure then why it worked in my other component w/o me having to do this:

class Dashboard extends Component {
  state = {
    movie: [],
    genres: [],
    rating: null
  };

  async componentDidMount() {
    const queryString = `${apiUrl}${this.props.match.params.id}?api_key=${key}`;

    const { data: movie } = await http.get(queryString);
    const genres = movie.genres;
    const rating = movie.vote_average.toFixed(1);

    this.setState({ movie, genres, rating });
  }
}

I know componentDidMount is called before the render method, but how come then we can use map() in the render method without getting an error?, because originally the array is undefined as well.

If you’re calling map on movie then it will work because the initial value of movie is an empty array. Also its kind of weird to set movie to an empty array, it shouldn’t be an object? Or maybe the name should be movies?

You can always return nothing or something like loading from render if you still can’t render it.

Example:

render() {
 if (!this.state.movie.vote_average) return "Loading";

  console.log(this.state.movie.vote_average.toFixed(1))
}

componendDidMount is called before render, but since it is async, react can’t wait it to finish before calling render. Which means it will call render with the default state at least once. You can check that by logging the full state in render.

1 Like

As I was talking here I just remembered that an empty array is not undefined, reason why I’ve been setting the value to an empty array to avoid getting errors when using map.

And yes, movie should be an object, because I am getting only one object in this component.

This was very helpful, now things are more clear to me. Thanks!