user9081229
user9081229

Reputation:

Can I write a if/else statement for Axios Get Method if condition is not met?

I am using Axios to get API data in ReactJS. I set up a search query that will take the user input and match it with the API where the data response is set as a state. I am having an issue where if the data I'm trying to receive does not exist in the API, the page returns with this error:

Unhandled Rejection (TypeError): Cannot read property 'medium' of null

  32 |     title: response.data.name,
  33 |     summary: response.data.summary,
  34 |     rating: response.data.rating.average,
> 35 |     image: response.data.image.medium,
  36 |     genre: response.data.genres,
  37 |   });
  38 | })

Is there a way to write and if/else statement inside the GET request to fix this problem?

import React, { Component } from 'react';

import SearchResults from '../SearchResults/SearchResults';
import AddButton from '../AddButton/AddButton';
import axios from 'axios';

class Searchbar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      searchTerm: ' ',
      title: ' ',
      summary: ' ',
      rating: ' ',
      image: ' ',
      genre: [],
    }
  }

  componentWillMount() {
    this.search();
  }

  updateSearchHandler = (event) => {
    this.search(this.refs.query.value);
  }

  search(query = "stranger-things") {
    const url = `http://api.tvmaze.com/singlesearch/shows?q=${query}`;
    axios.get(url).then(response => {
      this.setState({
        title: response.data.name,
        summary: response.data.summary,
        rating: response.data.rating.average,
        image: response.data.image.medium,
        genre: response.data.genres,
      });
    })
  }

  render() {
    let editedSummary = this.state.summary.replace(/(<p>|<b>|<\/p>|<\/b>)/g, '')
    let spiltGenre = this.state.genre.join(', ');

    return(
      <div>
        <input
          type="text"
          ref="query"
          onChange={this.updateSearchHandler}/>

        <SearchResults
        showTitle={this.state.title}
        showSummary={editedSummary}
        showRating={this.state.rating}
        showImage={this.state.image}
        showGenre={spiltGenre}/>

      <AddButton
        showTitle={this.state.title}
        showGenre={spiltGenre}/>
      </div>
    )
  }
}

  export default Searchbar;

Upvotes: 1

Views: 14289

Answers (2)

Brett DeWoody
Brett DeWoody

Reputation: 62773

Option 1 - Ternary Operator

You can use a ternary operator to test if response.data.image is defined. If so, return response.data.image.medium, if not return null or another value. A ternary operator works like this:

const isTrue = true;
const newVariable = (isTrue ? 'Its true' : 'Its false');

If isTrue is true, then newVariable is Its true. If isTrue is false, then newVariable is Its false.

Example

Here's a simplified example:

const response = {
  data: {
    name: "My Name",
    summary: "My Summary",
    rating: {
      average: "My Average"
    },
    genres: "My genres"
  }
}

const state = {
  title: response.data.name,
  summary: response.data.summary,
  rating: response.data.rating.average,
  image: response.data.image ? response.data.image.medium : "No image",
  genre: response.data.genres,
};

console.log(state);

Option 2

Here's another method using Object Destructuring. Destructuring allows us to create variables from the object property names, rename any if needed, and define default values in the case the property is undefined. To use this, we would destructure response.data into the 5 properties we want:

  • rename name to title
  • keep summary as summary
  • rename rating.average to rating
  • rename image.medium to medium, with a default value of null
  • rename genres to genre

We then need to pass these new constants to the state object.

I've provided 2 examples to show how it would handle a response with and without an image. First a response with an image property.

Example 1

const response = {
  data: {
    name: "My Name",
    summary: "My Summary",
    rating: {
      average: "My Average"
    },
    image: {
      medium: "My image"
    },
    genres: "My genres"
  }
};

const {
  name: title,
  summary,
  rating: {average: rating},
  image: {medium: image} = {medium: null},
  genres: genre
} = response.data;

const newState = {
  title,
  summary,
  rating,
  image, 
  genre
}

console.log(newState);

Example 2

And now a response without an image property.

const response = {
  data: {
    name: "My Name",
    summary: "My Summary",
    rating: {
      average: "My Average"
    },
    genres: "My genres"
  }
}

const {
  name: title,
  summary,
  rating: {average: rating},
  image: {medium: image} = {medium: null},
  genres: genre
} = response.data;

const newState = {
  title,
  summary,
  rating,
  image,
  genre
}

console.log(newState);

Upvotes: 1

Franklin
Franklin

Reputation: 891

You can do if/else in the callback of axios.

I would do:

image: response.data.image != null ? response.data.image.medium: '' ,

Or with if/else:

let imageMedium = '';
if (response.data.image != null) {
   imageMedium = response.data.image.meduim
}

Upvotes: 0

Related Questions