Discovering an item in a JSON Array based on a parameter utilizing a Promise - what's the best approach?

Upon making a JSON request, I received the following data:

{"page": 1,
  "results": [
    {
      "poster_path": "/9O7gLzmreU0nGkIB6K3BsJbzvNv.jpg",
      "adult": false,
      "overview": "Framed in the 1940s for the double murder of his wife and her lover, upstanding banker Andy Dufresne begins a new life at the Shawshank prison, where he puts his accounting skills to work for an amoral warden. During his long stretch in prison, Dufresne comes to be admired by the other inmates -- including an older prisoner named Red -- for his integrity and unquenchable sense of hope.",
      "release_date": "1994-09-10",
      "genre_ids": [
        18,
        80
      ],
      "id": 278,
      "original_title": "The Shawshank Redemption",
      "original_language": "en",
      "title": "The Shawshank Redemption",
      "backdrop_path": "/xBKGJQsAIeweesB79KC89FpBrVr.jpg",
      "popularity": 5.446135,
      "vote_count": 5250,
      "video": false,
      "vote_average": 8.32
    },
    {
      "poster_path": "/lIv1QinFqz4dlp5U4lQ6HaiskOZ.jpg",
      "adult": false,
      "overview": "Under the direction of a ruthless instructor, a talented young drummer begins to pursue perfection at any cost, even his humanity.",
      "release_date": "2014-10-10",
      "genre_ids": [
        18,
        10402
      ],
      "id": 244786,
      "original_title": "Whiplash",
      "original_language": "en",
      "title": "Whiplash",
      "backdrop_path": "/6bbZ6XyvgfjhQwbplnUh1LSj1ky.jpg",
      "popularity": 9.001948,
      "vote_count": 2072,
      "video": false,
      "vote_average": 8.28
    },

I am attempting to locate a specific object based on its Id using a service:

@Injectable()
export class MovieService {

    constructor(private http:Http) { }

    getMovies(): Promise<Movie[]>{

        return this.http.get('http://api.themoviedb.org/3/movie/top_rated?api_key=API-KEY')
            .toPromise()
            .then((res:Response) => res.json()['results'])

    }
    getMovie(id: number): Promise<Movie> {
        return this.getMovies()
            .then(movies => movies.find(movie => movie.id == id));

    }
}

However, when executing the getMovie() method, I encounter an EXCEPTION: Uncaught (in promise), with an error stating 'id undefined'. How can I successfully retrieve the desired object?

Answer №1

Check out my solution on Plunker to resolve your problem.

Plunker

I strongly recommend using Observables instead of Promises in this scenario.

These are the two methods included in your service:

getMovies() : Observable<any>{
    return this.http.get('./src/data.json')
}
getMovieById(id: number): Observable<any> {
    return this.getMovies().map( res =>{

      let response = res.json()['results'];

      return response.find(item => item.id === id)
    })
}

Here is the component code:

export class App {
  constructor(private movieService:MovieService) {
    this.movieService.getMovieById(278).subscribe(res => console.log(res))
  }
}

I won't delve deep into Observables here since there are plenty of resources available online. If you're unfamiliar with them, think of Observables as a combination of promises and event emitters.

Each time an event occurs, the observable emits that event to all subscribers. The subscribe method can be likened to a forEach loop.

Therefore,

this.movieService.getMovieById(278).subscribe(res => console.log(res))

can be understood as

this.movieService.getMovieById(278).forEach(res => console.log(res))

Whenever the Observable emits something, the emitted value will be processed by the forEach function.

I hope this explanation proves helpful.

Cheers!

Answer №2

After some investigation, I uncovered an error in my TopmoviesDetail component. The issue arose when calling the getMovie(id) function, as depicted below:

 ngOnInit(): void {
        this.route.params.forEach((params: Params) => {
            let id = +params['id'];
            this.movieService.getMovie(id)
                .then(movie => this.movie = movie);

        });
    }

In reviewing the template code, it became apparent that I had overlooked including *ngIf="movie". Once rectified, all functionalities returned to normal.

@Component({

    selector: 'topmovies',
    template: ` 
    <div *ngIf="movie">// I forgot to add this line
    <h2>{{movie.id}}</h2>
    <h2>{{movie.original_title}} </h2>
    </div>

    `
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

trpc - Invoking a route from within its own code

After reviewing the information on this page, it appears that you can invoke another route on the server side by utilizing the const caller = route.createCaller({}) method. However, if the route is nested within itself, is it feasible to achieve this by ...

Limiting the assignment of type solely based on its own type, without considering the components of the type

I have defined two distinct types: type FooId = string type BarId = string These types are used to indicate the specific type of string expected in various scenarios. Despite TypeScript's flexibility, it is still possible to perform these assignment ...

Angular CLI simplifies the process of implementing internationalization (i18n) for Angular

After diving into the Angular documentation on i18n and using the ng tool xi18n, I am truly impressed by its capabilities. However, there is one part that has me stumped. According to the documentation, when internationalizing with the AOT compiler, you ...

What steps should I follow to configure tastypie to support a JSONField?

Currently, I am encountering an issue where I receive a "BAD REQUEST: '' is not a valid JSON string." error message when attempting to post data to my tastypie API. The API I am working with contains a ModelResource that is linked to a model feat ...

Efficient method to identify distinct keys within a collection of objects using Typescript

https://i.sstatic.net/qHkff.png I am currently developing an angular application that includes: a group of filters and data records displayed in a table The columns in the table correspond to the filters, where each filter contains unique values from it ...

Converting literal types within simulated JSON data

I'm currently working with a JSON object that looks like this: { "elements": [ { "type": "abstract" }, { "type": "machine" }, { "type": "user" ...

Handling Errors in RXJS Angular - Utilizing .subscribe and Observable Strategy

For creating a new product using a backend API, the Angular frontend code needs to make a call to the API. I am interested in learning how to implement error handling with the use of .subscribe method. Currently, I am utilizing HTTPClient along with Observ ...

Integrating Ruby on Rails models to generate JSON output

I've been working on creating a JSON API endpoint using Ruby on Rails. After following the steps provided in this resource, I was able to successfully generate a JSON API for my models: The controller I have set up is: /api/v1/movies_controller.rb ...

Steps to transfer JSON data from view to controller using the redirect function in the CodeIgniter framework

Currently, I have JSON data on my view page which I successfully decoded to obtain an array as the output. Now, I am looking to pass this array to the controller using the redirect function. I attempted the following: $this->session->set_userdata(&a ...

Exploring the Flatmap Promise Feature in JavaScript

I'm sure this question has been asked before, but is there a way to flatten a promise in JavaScript? For example: let justAPromise: Promise<something> = aPromise.flatMap( a => getAnotherPromise()); Or like this: let promiseOfPromise: Prom ...

Button activated by specified row index in Angular test

I've been working on testing the enabling or disabling of a button based on the selected rowIndex in Angular 11. However, I'm facing an issue where the test expects component.deleteRoleButtonDisabled to be false but it always evaluates to true. D ...

Troubleshooting TypeScript in VSCode while working with Asp.Net Core 3.1

Attempting the method outlined in this inquiry has only been successful when using the "debugger" command in typescript code, as opposed to breakpoints. This is my launch.json file: { "version": "0.2.0", "compounds": [ { "name ...

Is there a way to showcase geojson data in a table using ng-repeat loop in Angular framework?

I have successfully created a table with search filters and pagination, but now I want to integrate it with a map as well. The issue I am facing is that I am having trouble accessing the geojson file correctly. Can someone assist me with this? Here is my ...

What types of configuration options does SparkSession offer?

I need help using SparkSession to convert JSON data from a file to RDD in a Spark Notebook. The JSON file is already available. val spark = SparkSession .builder() .appName("jsonReaderApp") .config("config.key.here", configValueHere) .enableH ...

A guide on extracting keys and values from a JSON object and saving them in an array with the useState hook in a React application

function Graph() { const [tcases, setCases] = useState([]); const [recovered, setRecovered] = useState([]); const [deaths, setDeaths] = useState([]); useEffect(() => { axios .get("https://disease.sh/v3/covid-19/historical/all?last ...

What is the best way to remove directory structure from the output using grunt-concat-json?

I'm having some trouble using grunt-concat-json with my specific directory structure. Here's how it currently looks: _src/ assembly/ _data/**/*.json The concat-json plugin is supposed to merge files that share the same path into one objec ...

Employing jq to transfer the value of a child property to the parent dictionary

My TopoJSON file contains multiple geometries, structured as follows: { "type": "Topology", "objects": { "delegaciones": { "geometries": [ { "properties": { "name": "Tlalpan", "municip": "012", ...

Passing parameters as JSON and using them as arguments in ActiveJob

During the upgrade process from Rails 4.2 to Rails 5, I encountered an issue when trying to pass params like [:members][:contact_ids] into ActiveJob. To address this problem, I attempted to convert it to JSON using the following code snippet: contact_id ...

Ways to obtain a referrer URL in Angular 4

Seeking a way to obtain the referrer URL in Angular 4. For instance, if my Angular website is example.com and it is visited from another PHP page like domaintwo.com/checkout.php, how can I detect the referring URL (domaintwo.com/checkout.php) on my Angul ...

Utilizing a single resolver for both parent and child routes in Angular 2

In my Angular 2.0 (stable version) application, I have a specific entity called project. The details of each project are spread across different sections/routes within the app: project/:id/overview project/:id/documents project/:id/logs and more The API ...