So erstellen Sie Ihre erste Ionic 4-App mit API-Aufrufen

Sie haben gerade bemerkt, dass Ionic 4 veröffentlicht wurde und möchten endlich mit der plattformübergreifenden App-Entwicklung beginnen? Nun, heute ist dein Tag! Wir werden Ihre erste Ionic 4-Anwendung mit HTTP-Aufrufen für die Open Movie-Datenbank erstellen!

Egal, ob Sie Ionic noch nicht kennen oder frühere Versionen verwendet haben, wir gehen alle Grundlagen durch. Wir werden beschreiben, wie Sie eine neue App einrichten , Routing und sogar API-Aufrufe, um asynchrone Daten in unserer App anzuzeigen .

Wenn Sie Ionic noch schneller lernen möchten, können Sie auch meine Ionic Academy besuchen, die für Entwickler wie Sie entwickelt wurde!

Fertig ? Geh !

Einrichten unserer Ionic 4 App

Wenn Sie Ionic noch nicht kennen, müssen Sie sicherstellen, dass der Node Package Manager installiert ist. Wenn Sie mit anderen Webtechnologien gearbeitet haben, bevor die Chancen gut stehen, haben Sie bereits alles, was Sie brauchen.

Wenn Sie Ionic noch nicht verwendet haben, müssen Sie es über npm installieren. Nach der Installation können Sie endlich Ihr Ionic 4-Projekt erstellen!

Um ein leeres Projekt einzurichten, können Sie die Ionic CLI verwenden, sodass wir ein neues Ionic 4-Projekt mit Angular-Unterstützung erhalten ( Sie können auch React oder Vue verwenden, bessere Unterstützung kommt später in diesem Jahr ).

Sobald das Projekt erstellt ist, cd wir in den Ordner. Wir verwenden die CLI, die die Angular-CLI unter der Haube verwendet, um neue Seiten für unsere App zu erstellen, die wir anzeigen möchten.

# Install Ionic if you haven't before npm install -g ionic # Create a blank new Ionic 4 app with Angular support ionic start movieApp blank --type=angular cd movieApp # Use the CLI to generate some pages and a service ionic g page pages/movies ionic g page pages/movieDetails ionic g service services/movie

Sie können Ihre App jetzt direkt aufrufen, indem Sie den folgenden Befehl in Ihrem Projekt ausführen:

ionic serve

Dadurch wird der Browser mit der Vorschau Ihrer App geöffnet, die automatisch neu geladen wird, sobald Sie Änderungen an Ihrem Projekt vornehmen.

Apropos Projekt, wir haben hier eine Reihe von Dateien und Ordnern. Mal sehen, was das alles bedeutet. Wir werden uns auf den src- Ordner unserer App konzentrieren, da wir uns vorerst nicht um den Rest kümmern müssen.

App

Dies ist der Ordner, in dem wir alle Codeänderungen vornehmen, die später in diesem Tutorial folgen. Es enthält bereits einen Home- Ordner, der im Grunde eine Seite ist, wie wir sie zuvor erstellt haben. Ich mag alle Seiten in ihren eigenen haben Seiten Ordner , so dass Sie den Home - Ordner als auch für jetzt entfernen können.

Die Seiten Ordner mit den tatsächlichen Ansichten / Seiten unserer App enthält, die das Element bedeutet , dass wir auf dem Bildschirm sehen. Im Moment haben wir hier bereits 2 Seiten und jede Seite, die Sie mit der CLI erstellen, enthält 4 Dateien:

  • * .module.ts: Die Winkelmodul für eine Seite. Jede Seite ist im Grunde ein eigenes Modul (bezogen auf die Angular-Architektur) mit Importen und Stilen
  • * .page.html: Das HTML- Markup für eine Seite
  • * .page.scss: Das Styling für die jeweilige Seite (mehr zum globalen Styling später)
  • * .page.spec.ts: Eine automatisch hinzugefügt Testen für Ihre Auslagerungsdatei. Gut, wenn Sie automatisierte Komponententests einrichten möchten
  • * .page.ts: Der Controller für eine Seite, die den Javascript-Code enthält, der die Funktionalität verwaltet

Der Dienstordner enthält unseren zuvor erstellten Dienst. Hier geht es darum, Ihre App nach Best Practices zu strukturieren und Bedenken zwischen der Ansicht und den tatsächlichen Daten Ihrer App zu trennen. Der Service kümmert sich um die Bearbeitung der API-Aufrufe und gibt die Daten später einfach an unsere Ansicht zurück!

Vermögenswerte

Dieser Ordner enthält alle Bilder, Schriftarten oder sonstigen Elemente, die Sie später für Ihre App benötigen.

Umgebungen

Von Zeit zu Zeit verfügt Ihr Projekt möglicherweise über eine Entwicklungs-, Staging- und Produktionsumgebung mit verschiedenen Servern, auf die Ihre App abzielt. Der Umgebungsordner hilft beim Einrichten von Informationen für verschiedene Umgebungen. Wir können unsere Ionic-App später mit einem Befehlszeilenflag erstellen , das automatisch die richtigen Werte annimmt. Sehr praktisch!

Thema

Dieser Ordner enthält nur die Variable.scss , die vordefinierte Farbinformationen von Ionic enthält. Wir können diese Datei jederzeit ändern und sogar ein Tool wie den Ionic Color Generator verwenden, um unsere eigene Version dieser Datei zu erstellen!

Außerhalb des Ordners haben wir auch die Datei global.scss. Hier können wir einige SCSS schreiben, die global auf unsere App angewendet werden. Wir können es auch nur für eine Seite in ihren eigenen Styling-Dateien definieren.

Andere Dateien

Die relevanteste der anderen Dateien ist möglicherweise die index.html, da diese Datei wie jede andere Website den Einstiegspunkt in unsere App markiert! Im Moment müssen wir hier zwar nichts ändern, aber jetzt beginnen wir mit dem eigentlichen Code.

Voraussetzung Routing & HTTP-Anrufe

Mit Ionic 4 wechseln wir von einem proprietären Routing-Konzept zum Standard-Angular-Router. Das Markup sieht am Anfang vielleicht etwas schwieriger aus, macht aber durchaus Sinn.

Für alle Verbindungen in Ihrer App richten Sie Routing-Informationen im Voraus ein - genau wie Sie auf einer Website navigieren!

In unserer App benötigen wir 2 Routen:

  • / movies - Navigieren Sie zu unserer ersten Seite, auf der eine Liste der Filme angezeigt werden soll
  • / movies /: id - Wir möchten die Details für einen Film anzeigen können, also fügen wir der Route eine param : id hinzu , die wir dynamisch auflösen können

Wir müssen auch die entsprechende Seite ( genauer : das Modul der Seite) mit der Route verbinden, damit Angular weiß, wie eine bestimmte Route aufgelöst wird. Wir liefern diese Informationen mit loadChildren, das tatsächlich nur eine Zeichenfolge zum Modulpfad erhält .

Dies bedeutet, dass wir hier nicht wirklich ein anderes Modul importieren, daher verwenden die Seiten das verzögerte Laden. Das heißt, sie werden erst geladen, wenn wir dorthin navigieren!

Um unsere Routing-Informationen einzurichten, öffnen Sie unsere app / app-routing.module.ts und ändern Sie sie in:

import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: '', redirectTo: 'movies', pathMatch: 'full' }, { path: 'movies', loadChildren: './pages/movies/movies.module#MoviesPageModule' }, { path: 'movies/:id', loadChildren: './pages/movie-details/movie-details.module#MovieDetailsPageModule' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }

Durch diese Änderung haben wir auch die Startseite getrennt, die sich ursprünglich im Projekt befand (und die Sie möglicherweise bereits zu diesem Zeitpunkt gelöscht haben).

Jetzt lädt die App unsere Filmseite als erste Seite, großartig! Sie sollten diese Änderung auch bereits in Ihrer laufenden ionic serveInstanz bemerken .

Tipp: Wenn Sie ein besseres Gefühl dafür bekommen möchten, wie Ihre App auf einem realen Gerät aussehen wird, können Sie sie auch ausführen, ionic labanstatt sie bereitzustellen, aber Sie müssen das Paket im Voraus installieren:

# Install the Lab Package npm i @ionic/lab # Run your app with device preview and platform styles ionic lab

Dieses Paket wurde zuvor mit jeder neuen App gebündelt, muss aber jetzt für Ionic 4 installiert werden.

/ Tipp Ende

Wir müssen auch eine weitere Änderung an unserer App vornehmen, da wir HTTP-Aufrufe tätigen möchten . Daher müssen wir ein anderes Angular-Modul importieren, um diese Anforderungen zu stellen.

Die Vorgehensweise ist die gleiche wie bei Ionic 3. Wir müssen nur die HttpClientModuleDatei zu unserer Hauptmoduldatei hinzufügen und sie dem Array solcher Importe in unserer app / app.module.ts hinzufügen :

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

Bevor wir uns mit mehr Ionic 4-Code befassen, müssen wir zuerst den Dienst einrichten, der unsere App antreibt und alle HTTP-Anforderungen verarbeitet, die wir später aufrufen möchten.

HTTP-Anfragen stellen

Ein Dienst ist derselbe wie in früheren Versionen eines Anbieters und kann in unseren Controller eingefügt werden, um dessen Funktionen aufzurufen.

Um die Open Movie-Datenbank nutzen zu können, müssen Sie einen API-Schlüssel anfordern und in unseren Service einfügen. Der Vorgang ist kostenlos. Fahren Sie also sofort fort.

Mit der API können wir jetzt nach Zeichenfolgen suchen und Ergebnisse in Form von Filmen, Episoden oder sogar Spielen erhalten. Außerdem können wir detaillierte Informationen für ein bestimmtes Objekt dieser Ergebnisse erhalten, was einen perfekten Anwendungsfall für unsere erste Ionic 4-App darstellt!

Unser Service benötigt nur 2 Funktionen:

  • searchData(): Diese Funktion sucht nach Ergebnissen für einen bestimmten Titel und Suchtyp - eine Aufzählung, die wir im Voraus definiert haben, um die Typen darzustellen, die wir mit TypeScript an die API übergeben können!
  • getDetails(): Diese Funktion gibt die detaillierten Informationen für ein bestimmtes Element zurück und wird auf unserer Detailseite verwendet

Beide Funktionen geben Observableein Versprechen für Steroide zurück. Kein Ernst, es ist wie ein Strom von Ereignissen, die wir abonnieren können . Die Erklärung dieses Konzepts würde einen weiteren Beitrag erfordern. Lassen Sie es uns zunächst verwenden und bedenken, dass unsere beiden Funktionen asynchron sind - sie geben die API-Daten nicht sofort zurück.

Ändern Sie nun Ihre services / movie.service.ts in:

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; // Typescript custom enum for search types (optional) export enum SearchType { all = '', movie = 'movie', series = 'series', episode = 'episode' } @Injectable({ providedIn: 'root' }) export class MovieService { url = '//www.omdbapi.com/'; apiKey = ''; // <-- Enter your own key here! /** * Constructor of the Service with Dependency Injection * @param http The standard Angular HttpClient to make requests */ constructor(private http: HttpClient) { } /** * Get data from the OmdbApi * map the result to return only the results that we need * * @param {string} title Search Term * @param {SearchType} type movie, series, episode or empty * @returns Observable with the search results */ searchData(title: string, type: SearchType): Observable { return this.http.get(`${this.url}?s=${encodeURI(title)}&type=${type}&apikey=${this.apiKey}`).pipe( map(results => results['Search']) ); } /** * Get the detailed information for an ID using the "i" parameter * * @param {string} id imdbID to retrieve information * @returns Observable with detailed information */ getDetails(id) { return this.http.get(`${this.url}?i=${id}&plot=full&apikey=${this.apiKey}`); } }

Ich habe den Funktionen auch einige Dokumentationen hinzugefügt - mit einem Tool wie Compodoc können Sie jetzt eine schöne Dokumentation erstellen!

Okay, jetzt sind wir endlich bereit für etwas mehr Ionic 4 Code!

Nach Filmen suchen

Wir starten unsere Apps-Funktionalität mit den Dingen, die im Hintergrund passieren, und bauen dann die Ansicht darauf auf.

Im Moment müssen wir also die Logik implementieren, um einen Suchbegriff und einen Typ an unseren Service zu senden und die Ergebnisse zu erhalten. Daher injizieren wir den Service über unseren Konstruktor, damit er der Klasse zur Verfügung steht.

In einer anderen Funktion, die wir aufrufen, rufen searchChanged()wir jetzt einfach die entsprechende Funktion unseres Dienstes auf und setzen das Ergebnis auf eine lokale Variable b> results. Unsere Ansicht wird später die Daten verarbeiten, die von der API stammen, und sie mit dieser Variablen anzeigen.

Wir behalten auch 2 weitere Variablen für das searchTerm bei und geben innerhalb unserer Klasse ein, die wir an den Service übergeben. Wir werden uns auch aus der Sicht mit ihnen verbinden, damit wir sie ändern können.

Fahren Sie nun mit dem Code für Ihren Controller in den Seiten / movies / movies.page.ts fort :

import { MovieService, SearchType } from './../../services/movie.service'; import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-movies', templateUrl: './movies.page.html', styleUrls: ['./movies.page.scss'], }) export class MoviesPage implements OnInit { results: Observable; searchTerm: string = ''; type: SearchType = SearchType.all; /** * Constructor of our first page * @param movieService The movie Service to get data */ constructor(private movieService: MovieService) { } ngOnInit() { } searchChanged() { // Call our service function which returns an Observable this.results = this.movieService.searchData(this.searchTerm, this.type); } }

In der Ansicht, die dem Ionic 3-Code sehr ähnlich sieht, haben nur einige der Elemente ihre Namen und Eigenschaften geändert. Für alle, die Ionic im Allgemeinen noch nicht kennen: Willkommen zu Ihren ersten Ionic-Komponenten !

Eine Seite kann in drei Bereiche unterteilt werden: Kopfzeile, Inhalt, Fußzeile. In unserem Fall möchten wir keine Fußzeile, daher definieren wir nur den Kopfbereich mit einem Titel und den Inhalt mit unseren eigentlichen Elementen für die Suche.

Das erste Element, das sich auf die Suche auswirkt ion-searchbar, ist eine einfache Eingabe, die Sie in vielen Apps zuvor gesehen haben, um nach einem Begriff zu suchen.

Wir möchten unsere Suchfunktion immer aufrufen, wenn sich der Typ oder searchTerm ändert. Wir können dies tun, indem wir das (ionChange) -Ereignis einiger unserer Elemente abfangen.

Unten haben wir eine Auswahl-Dropdown-Liste mit Optionen und dem entsprechenden Wert für die verschiedenen Typen, die wir an die API zurückgeben könnten.

Sie sollten auch die Syntax [(ngModel)] beachtet haben, über die beide Elemente mit unseren Controller-Eigenschaften verbunden sind. Wenn sich eine Seite ändert, erhält die andere automatisch auch den neuen Wert (auch als 2-Wege-Datenbindung bezeichnet ).

Also haben wir die Suche gestartet und fügen jetzt eine weitere Liste mit Elementen unter unseren vorherigen Komponenten hinzu.

Für die Liste verwenden wir eine Iteration über unsere Ergebnisvariable. Da diese Variable ein Observable ist (denken Sie an die Implementierung in unserem Service), müssen Sie ein Angular Pipe hinzufügen “| asynchron “dazu. Die Ansicht abonniert das Observable und behandelt die Änderungen entsprechend.

We also add the routing directly to this element by using [routerLink]. We construct the path that we want to open when we click on the element. We use the imdbID property of the item so we can resolve the information on our details page later.

Besides that, we create the markup for one item using the Poster which is an image, the title, year and finally also a cool icon at the and based on the type of the item. Yes, those cool icons are already bundled with your app and are called Ionicons!

With all of that in mind change your pages/movies/movies.page.html to:

  My Movie Search      Select Searchtype  All Movie Series Episode      

{{ item.Title }}

{{ item.Year }}

By now you should be able to search for a specific term inside your app and get a list of results — that’s already a big win!

If you are coming form Ionic 3 you might have also noted another new property called slot so here’s some info on that:

Ionic 4 components are built using Stencil (yeah, they actually created that tool as well!) so they are standard web components — you could import them basically everywhere on the web! These components also use the Shadow DOM API and are basically living outside of the scope of your regular DOM elements.

That means also standard styling will sometimes not affect these components like it was possible in previous versions!

In order to get information into these components, we can inject certain parts of HTML into their slots that are defined on these elements. You can see how their implementation looks like on the example of the ion-item we used here.

Presenting Detailed Information

Ok enough of background information, let’s put some more work into the details page of our app. We have implemented a route and we also created a button that passed an ID with that route so the details page will be open, but we need to get access to the ID!

With previous Ionic versions we could easily pass whole objects to new pages, this is now not a best practice anymore. Instead, we pass only small chunks of information (like an ID) with the URL. Otherwise, you would end up with a huge JSON stringified term inside the URL. This isn’t really something we want to have.

To get access to this ID field (that we already defined inside our routing in the beginning) we can use the ActivatedRoute and its properties.

So after we extract the ID from the params we can make another call to our service (that we injected through the constructor again) and get the detailed information for whatever ID we got.

Nothing really new so let’s add the following code to our pages/movie-details/movie-details.page.ts:

import { MovieService } from './../../services/movie.service'; import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-movie-details', templateUrl: './movie-details.page.html', styleUrls: ['./movie-details.page.scss'], }) export class MovieDetailsPage implements OnInit { information = null; /** * Constructor of our details page * @param activatedRoute Information about the route we are on * @param movieService The movie Service to get data */ constructor(private activatedRoute: ActivatedRoute, private movieService: MovieService) { } ngOnInit() { // Get the ID that was passed with the URL let id = this.activatedRoute.snapshot.paramMap.get('id'); // Get the information from the API this.movieService.getDetails(id).subscribe(result => { this.information = result; }); } openWebsite() { window.open(this.information.Website, '_blank'); } }

We also added another function to open a website using the window object and the information from the data of the API that we stored in the local information variable.

Now we just need to create a view based on the JSON information of the API. It always helps to log() out the info you got so you see keys that you can use to display some values.

In our case, we use the Ionic card component and add the image and some items with information and more icons (did I say I really like the Ionicons?).

We also added a button below that card that will be displayed if the result information contains the website key. We just have to add our function to the (click) event of the button in order to hook everything up!

On another note, we also have to add an ion-back-button to the header of that page in order to get a nice little back arrow to our previous movie list page. This was automatically done in v3 but needs to implemented manually as of v4!

Now finish your details view by changing your pages/movie-details/movie-details.page.html to:

     {{ information?.Genre }}       {{ information.Title }}   {{ information.Year }}     {{ information.Plot }}   {{ information.imdbRating }}    {{ information.Director }}    {{ information.Actors }}    Open Website    

If you now take a look at your browser you might notice that the image looks waaaay to big as its taking all the space available. Let’s change this through some good old CSS so open your pages/movie-details/movie-details.page.scss and insert:

.info-img { max-height: 30vh; object-fit: contain; padding: 10px; }

Now our results look a lot more appealing.

We can search, select a movie type, dive into a search result and have a fully functional Ionic 4 app with HTTP calls finished!

Conclusion

While it was a straight forward experience to build our first Ionic 4 app there are so many things we haven’t talked enough about.

UI patterns like Tabs and side menu, CSS variables, responsive layout and PWA to just name a few on the side of Ionic and Angular.

And we haven’t even touched the Cordova side of things to actually build this app into a real native mobile app!

If you want to learn how to develop Ionic 4 apps as fast as possible and get them to the iOS & Android app stores quickly you can join the Ionic Academy today and enjoy expert screencasts, a library of quick wins and a community to support you on your journey!

And of course, I (Simon) am also present inside to answer all your questions all the time

You can also find a video version of this guide below!

Originally published at ionicacademy.com on January 24, 2019.