An Introduction to HTTP Requests & Fetching Data in Ionic

 

imj


Welcome!

Today, we'll learn more about HTTP requests and how to structure our app using providers.

We'll use the Star Wars API, a public, free API that returns JSON data, which we need right now.

1. Basic HTTP Calls

First, we need to tell our app to add another Angular module that lets it make HTTP requests. It is already set up, so all we have to do is load it and add it to our src/app/app.module.ts file like this:

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {RouteReuseStrategy} from '@angular/router';
import {IonicModule, IonicRouteStrategy} from
'@ionic/angular';
 
import {AppComponent} from './app.component';
import { HttpClientModule } from '@angular/common/http';
 
@NgModule({
  declarations: [AppComponent],
entryComponents: [],
  imports: [
    BrowserModule,
    HttpClientModule,
    IonicModule.forRoot()
  ],
  providers: [
    {provide: RouteReuseStrategy, useClass: IonicRouteStrategy}
  ],
 bootstrap: [AppComponent],
})
export class AppModule {}


Now we can make HTTP calls to any website we want.

Using external resources like this is an asynchronous operation.

Whatever you're trying to call takes time, and this happens in the background of our app and returns data at some point.

We can make use of Promises & Observables with Angular. If you've used AngularJS, you may already know about Promises. When called, they return either a result or an error at some point.

Observables are a bit newer and give you more control. For example, you can cancel an observable or get more than one return value. You can think of it more as a series of promises that can be made with just one click.

So, when we send a request to the Swapi, we get back an observable that we can put into a local variable. We make a classic GET request by using the standard Angular Http service.

then() was used to handle a classic promise, which was called once when the result came in.

Now that we have an observable, we need to subscribe() to the data stream that might come back. We finally got the result of our call inside that block.


Open your src/pages/films/films.ts and change it to:

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
 
@Component({
  selector: 'page-films',
  templateUrl: 'films.html',
})
export class FilmsPage {
  films: any;
 
  constructor(
public router: Router,
public httpClient: HttpClient)
{
const url = 'https://swapi.co/api/films';
    this.films = this.httpClient.get(url);
    this.films
    .subscribe(data => {
      console.log('my data: ', data);
    })
  }
}

If you open your app, it will take a short while to start (don't forget: async!), and you should see a log message in your debugging area. It is where we can find and look at the different objects of the call we made.



NOTE: If you get a message like this in your browser, it means:

Failed to load http://swapi.co/api/films: Redirect from ‘http://swapi.co/api/films’ to ‘https://swapi.co/api/films’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8100’ is therefore not allowed access.


The CORS problem will appear in the browser (but not in a real app!). You can add this Chrome extension and turn it on, and then the requests should also work in your browser.

If you've reached this point, you're pretty close to being able to show them, so let's not only log them but also show them in our view.

2. Showing Asynchronous Data

We can easily use observables right from our view with Angular. We don't have to wait for the result and then assign it. Instead, we can set the variable to the development of our HTTP call and do the rest in the view!

Therefore update the src/pages/films/films.ts back to a more simplified version:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';

@Component({
  selector: 'page-films',
  templateUrl: 'films.html',
})
export class FilmsPage {
  films: any;
 
  constructor(
    public router: Router,
      private httpClient: HttpClient
      ) {
const url = 'https://swapi.co/api/films';
    this.films = this.httpClient.get(url);  
  }
 
  openDetails(film) {
    this.router.navigate(['/filmDetailPage'], {
      queryParams: {
        film: JSON.stringify(film)
      }
    });
  }

}


Also, when we click the "next page" button, we now send a "film" object, which comes from our view to the "openDetails()" function.


We got a few new things in the following code block, such as:

  • *ngFor: A way to go through an array and make several elements of the same type.
  • | async: Called a "Pipe," this tells Angular to keep an eye on this variable because it will change in the future.

  • ?: An operator that tells Angular that the variable might be null, so please don't crash.

We make a new film object every time we go through our loop. This object is sent straight to the click event and will be sent to the next page.

This loop will be used to add several items to the Ionic list. It is a pervasive pattern in Angular apps.

In each loop, we add the film's name to the button. When we're done, we'll have a list of controls that can be used to open each film's detail page.

Go ahead and change your src/pages/films/films.html to:

<ion-header>
  <ion-toolbar color="primary">
    <ion-title>Films</ion-title>
  </ion-toolbar>
</ion-header>
 
<ion-content>
<ion-list>
  <ion-item *ngFor="let film of (films | async)?.results"
(click)="openDetails(film)">
    {{ film.title }}
  </ion-item>
</ion-list>
 
</ion-content>


The last thing is to update the details page, which currently doesn't show our data.

Our push function already sends the data to that page, so we need to handle it right. So, replace src/pages/film-details/film-details.ts with:

import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'
;
 
@Component({
  selector: 'page-film-details',
  templateUrl: 'film-details.html',
})
export class FilmDetailsPage {
  film: any;
 
  constructor(
      private router: Router,
      private route: ActivatedRoute
    ) {
      this.route.queryParams.subscribe((res) => {
        this.film = JSON.parse(res.film);
    });
  }
}

Like before, we're getting the value and putting it in a local variable. Now we can use that variable inside our view to set the title and show a great little card with the beginning of the chosen Star Wars movie.

Open src/pages/film-details/film-details.html and change the view to read the values from our variable:


<ion-header>
  <ion-toolbar>
    <ion-title>{{ film.title }}</ion-title>
  </ion-toolbar>
</ion-header>
 
<ion-content class="ion-padding">
  <ion-card>
    <ion-card-content>
      {{ film.opening_crawl }}
    </ion-card-content>
  </ion-card>
</ion-content>

With just a few lines of angular/ionic code, you can now get a list of movies and show the data for each one.

Fetching


I'm always surprised when I use a REST API; the data comes in after I set it up once for the general case. Perhaps you're like me.

Anyway, we can make a few changes to how our app is built, which is a best practice for Ionic apps.

Next Steps

Congratulations!
You already know much about HTTP requests and can do them, so good job!

I’m sure you can do this HTTP. If you have any questions, you can ask them in the section for comments. Subscribe to us on YouTube.

Happy Coding,
Hammad

Post a Comment

0Comments
Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !