lauragift21
lauragift21

Reputation: 117

Map a Json file with response from Api in Vuejs

I'm currently getting data from themoviedb.com API. but I discovered the request doesn't include the specific genres for each movie. I created a separate json file that contains all the genres I need. Is there a way I can map data in my genres.json files to the remote API request?

{
  "genres": [
    {
      "id": 28,
      "name": "Action"
    },
    {
      "id": 12,
      "name": "Adventure"
    },
    {
      "id": 16,
      "name": "Animation"
    },
    {
      "id": 35,
      "name": "Comedy"
    },
    {
      "id": 80,
      "name": "Crime"
    },
    {
      "id": 99,
      "name": "Documentary"
    },
    {
      "id": 18,
      "name": "Drama"
    },
    {
      "id": 10751,
      "name": "Family"
    },
    {
      "id": 14,
      "name": "Fantasy"
    },
    {
      "id": 36,
      "name": "History"
    },
    {
      "id": 27,
      "name": "Horror"
    },
    {
      "id": 10402,
      "name": "Music"
    },
    {
      "id": 9648,
      "name": "Mystery"
    }
  ]
}

Upvotes: 0

Views: 2797

Answers (2)

Guillaume Meral
Guillaume Meral

Reputation: 462

I do not understand how any of this is related to vue.js as it looks like a pure javascript logic problem. Here are some advices that could help you :

Rather than keeping an hardcoded list of Categories which is susceptible to get outdated and to break your application, i would recommend you to get them from the api itself : https://developers.themoviedb.org/3/genres/get-movie-list

When having the result of both your genres and find request you could add the genre names to the object you are getting like so :

// Here the result of the 'genres' call
var genres = [...]

function getGenreName(genreId) {
  var genre = genres.find(function(element) {
    return element.id === genreId
  })
  if (!genre) return 'unknownGenre'
  return genre.name
}

movieResults.map(function(movieResult) {
  movieResult['genreNames'] = movieResult.genre_ids.map(function(genreId) {
    return getGenreName(genreId)
  })
  return movieResult
})

Upvotes: 0

Bert
Bert

Reputation: 82439

This is how you might do that.

Basically with Vue, you want to create a computed value that maps over the response from the movie API and adds the genre information to the response.

console.clear()
const genres = [
    {
      "id": 28,
      "name": "Action"
    },
    {
      "id": 12,
      "name": "Adventure"
    },
    {
      "id": 16,
      "name": "Animation"
    },
    {
      "id": 35,
      "name": "Comedy"
    },
    {
      "id": 80,
      "name": "Crime"
    },
    {
      "id": 99,
      "name": "Documentary"
    },
    {
      "id": 18,
      "name": "Drama"
    },
    {
      "id": 10751,
      "name": "Family"
    },
    {
      "id": 14,
      "name": "Fantasy"
    },
    {
      "id": 36,
      "name": "History"
    },
    {
      "id": 27,
      "name": "Horror"
    },
    {
      "id": 10402,
      "name": "Music"
    },
    {
      "id": 9648,
      "name": "Mystery"
    }
  ]

new Vue({
  el: "#app",
  data:{
    genres,
    movies: null
  },
  computed:{
    moviesWithGenre(){
      // if the movies haven't been populated from the AJAX response yet
      // return an empty array
      if (!this.movies) return []
      
      return this.movies.map(movie => {
        return {
          // add all the existing movie properties
          ...movie,
          // add the genres
          genres: movie.genre_ids
                    // remove the genres we don't know
                    .filter(id => this.genres.map(g => g.id).includes(id))
                    // get the name
                    .map(id => this.genres.find(g => g.id === id).name)
        }
      })
    }
  },
  created(){
    var url = "https://api.themoviedb.org/3/movie/popular?api_key=8e3003c0c81633dc53b9d15ffa3399e1&language=en-US&page=1"
    axios.get(url)
      .then(response => this.movies = response.data.results)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<div id="app">
  <ul>
    <li v-for="movie in moviesWithGenre">
      {{movie.original_title}}
      <ul>
        <li v-for="g in movie.genres">{{g}}</li>
      </ul>
    </li>
  </ul>
</div>

Upvotes: 1

Related Questions