Flattern: Wie CRUD mit PostgreSQL? Teil 2

Ich werde heute einige spannende Themen teilen, wie zum Beispiel:

  • Wie erstellt man RESTful API auf einem Webserver mit Dart und Aqueduct mit Integration von Postgresql.
  • Wie man mit der Aqueduct-Anwendung eine mobile Flutter-App erstellt und grundlegende CRUD-Funktionen ausführt. Du bist hier

Im vorherigen Beitrag habe ich erläutert, wie Sie Ihren Webserver für die Implementierung von RESTful-API mithilfe von Aqueduct mit Postgresql einrichten. In diesem Beitrag werden wir damit beginnen, unsere Flatter-App für die Interaktion mit unserer Webanwendung zu erstellen.

So richten Sie das Flutter-Projekt ein

Erstellen Sie ein neues Flutter-Projekt mit flutter_crud_demo. Wenn Sie Visual Studio-Code verwenden, können Sie ein neues Projekt über Ansicht> Befehlspalette> Neues Projekt flattern> Projektnamen eingeben> Verzeichnis zum Speichern Ihres Projekts auswählen erstellen. Wenn der Arbeitsbereich initialisiert ist, löschen Sie die Datei widget_test.dart und leeren Sie den Inhalt der Datei main.dart.

Lesefunktion

Zukünftiger Erbauer

Mit Future Builder können wir eine Listenansicht rendern, sobald wir unsere Datenliste asynchron erhalten. Der zukünftige Builder verfügt über 2 Parameter. Einer ist die zukünftige Methode, mit der wir die Liste der Daten abrufen, und der andere ist der Builder, den wir mit den Daten erstellen möchten. Die Verwendung von Future Builder ermöglicht es uns, dem Benutzer einen CircularProgressIndicator anzuzeigen, bevor die Daten fertig sind, und ListView anzuzeigen, wenn der Abruf abgeschlossen ist. Ersetzen Sie in unserem Gerüstkörper durch den folgenden Code.

Körper: neuer Container (
  Kind: neuer FutureBuilder > (
    Zukunft: getAll (),
    Erbauer: (Kontext, Momentaufnahme) {

      if (snapshot.hasData) {
        neuen ListView.builder zurückgeben (
          itemCount: snapshot.data.length,
          itemBuilder: (Kontext, Index) {
            neue Spalte zurückgeben (
              crossAxisAlignment: CrossAxisAlignment.start,
              Kinder:  [
                neuer Text (snapshot.data [index] .name,
                  Stil: neuer Textstil (fontWeight: FontWeight.bold),
                neuer Teiler ()
              ]
            );
          }
        );
      } else if (snapshot.hasError) {
        neuen Text zurückgeben ("$ {snapshot.error}");
      }

      // Standardmäßig wird ein Ladespinner angezeigt
      return new CircularProgressIndicator ();
    },
  ),
),

Als nächstes müssen wir die Methode getAll () implementieren, um die Liste der Helden von unserem Webserver abzurufen. Unsere Methode gibt eine Futureof-Typenliste des Helden zurück. Innerhalb der Funktion rufen wir auf und warten auf http.get (_heroesUrl). Warten ermöglicht es uns, auf eine Antwort zu warten, bevor wir zur nächsten Zeile übergehen. Die Funktion getAll () muss mit async markiert sein, um wait innerhalb der Methode verwenden zu können. Aus der Antwort rufen wir die Nachricht ab und wandeln sie in unsere um

Zukunft > getAll () async {
  endgültige Antwort = warte auf http.get (_heroesUrl);
  print (response.body);
  Liste responseJson = json.decode (response.body.toString ());
  List  userList = createHeroesList (responseJson);
  return userList;
}

Wir müssen einige Bibliotheken für einige Hilfsfunktionen importieren.

import 'dart: convert';
import 'dart: async';
importiere 'package: http / http.dart' als http;

Lassen Sie uns einen Klassenruf Held erstellen. Diese Klasse nimmt eine ganze Zahl für id und eine Zeichenfolge als Namen auf.

Klasse Held {
  Held ({this.id, this.name});
  final int id;
  String name;
}

Fügen Sie in der Klasse _MyHomePageState die statische const _heroesUrl hinzu, die unsere localhost-URL enthält.

static const _heroesUrl = 'http: // localhost: 8888 / heroes';

Lassen Sie uns die Flutter-App ausführen. Denken Sie auch daran, Ihre Webserver-Anwendung mit dem Befehl aqueduct serve zu starten.

Wir können eine Liste von Helden in unserer Flutter-App bekommen

Löschfunktion

Ab hier führen wir eine Enumeration ein, um den Status einer http-Anfrage zu speichern. Jede http-Anforderung sollte den Typ HttpRequestStatus zurückgeben.

enum HttpRequestStatus {
  NICHT DURCHGEFÜHRT,
  GETAN,
  ERROR
}

Unzulässig

Wir werden Swipe to Delete implementieren, ein sehr verbreitetes Muster in mobilen Apps. Zu diesem Zweck tauschen wir die Spalte wie unten gezeigt gegen "Nicht teilbar" aus. Wir fordern dann an, einen Helden anhand seiner ID im Parameter onDismissed zu löschen. Die Methode deleteHero gibt eine Zukunft zurück, nämlich den httpRequestStatus. Wenn der Status fertig ist, werden wir Sie bitten, den Bildschirm mit setState () neu zu zeichnen.

neuen ListView.builder zurückgeben (
    itemCount: snapshot.data.length,
    itemBuilder: (Kontext, Index) {
      var item = snapshot.data [index];

      Rückgabe unzulässig (
        key: Key (item.id.toString ()),
        onDismissed: (direction) async {
          httpRequestStatus = warte auf deleteHero (item.id);
          if (httpRequestStatus == HttpRequestStatus.DONE) {
            setState (() {
              snapshot.data.removeAt (index);
            });
          }
        },
        Hintergrund: Container (Farbe: Colors.red),
        child: ListTile (title: Text ('$ {item.name}')),
      );
    });

Die Methode deleteHero lautet wie folgt

Zukünftige deleteHero (int id) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  final url = '$ _heroesUrl / $ id';
  endgültige Antwort = http.delete abwarten (URL, Header: _headers);
  if (response.statusCode == 200) {
    print (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }

  return httpRequestStatus;
}
Streichen Sie, um den Helden zu löschen

Funktion hinzufügen

Fügen Sie unter der App-Leiste ein Widget-Symbol hinzu, damit der Benutzer einen Helden hinzufügen kann.

AppBar: Neue AppBar (
  Titel: neuer Text ('Flutter CRUD Demo'),
  Aktionen:  [
    IconButton (
      icon: Icon (Icons.add),
      onPressed: _addHeroService,
      Tooltip: 'Neuen Helden hinzufügen',
    )
  ],
),

Im _addHeroService rufen wir _openDialogAddHero auf, um einen neuen Bildschirm für Benutzereingaben zum Namen des Helden zu öffnen. Diese Methode gibt einen neuen Heldennamen zurück, den wir dann mit createHero aufrufen. Wenn der Heldenname erfolgreich aktualisiert wurde, rufen wir setState () auf, um den Bildschirm neu zu zeichnen.

void _addHeroService () async {
  String name = warte auf _openDialogAddHero ();
  HttpRequestStatus httpRequestStatus = warte auf createHero (name);
  if (httpRequestStatus == HttpRequestStatus.DONE) {
    setState (() {
      
    });
  }
}

Fügen wir statische const _headers hinzu, um den Inhaltstyp des http-Headers zu speichern.

static final _headers = {'Content-Type': 'application / json'};

Der folgende Code sendet eine Anforderung zum Erstellen eines neuen Helden an die Webserveranwendung.

Future createHero (String name) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  endgültige Antwort = warte auf http.post (_heroesUrl,
      headers: _headers, body: json.encode ({'name': name}));
  if (response.statusCode == 200) {
    print (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }

  return httpRequestStatus;
}
Wir können jetzt neue Helden hinzufügen

Update-Funktion

Schließlich bleibt uns noch eine letzte Funktion, nämlich die Aktualisierung des Heldennamens. Wir möchten, dass der Benutzer auf einen vorhandenen Helden tippt, um den Namen zu aktualisieren. Dazu fügen wir in ListTile ein onTap hinzu, das die Methode _updateHeroService aufruft und an diesem Index der Liste die ID und den Namen des Helden übergibt. Ähnlich wie beim _addHeroService, der den Namen aus dem Popup-Dialogfeld abruft und an updateHero übergibt. Der Bildschirm wird dann neu gezeichnet, wenn das UpdateHero erfolgreich ist.

Future _updateHeroService (int id, String name) async {
  String updatedName = warte auf _openDialogUpdateHero (id, name);
  HttpRequestStatus httpRequestStatus = warte auf updateHero (id, updatedName);
  if (httpRequestStatus == HttpRequestStatus.DONE) {
    print (httpRequestStatus.toString ());
    setState (() {
      
    });
  }
}

Das Folgende ist der Code für updateHero

Future updateHero (int id, String name) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  final url = '$ _heroesUrl / $ id';
  endgültige Antwort = http.put abwarten (url,
      headers: _headers, body: json.encode ({'id': id, 'name': name}));
  if (response.statusCode == 200) {
    print (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }
}
Tauschen wir Hawkeye mit Thor aus

Abschließend haben wir uns mit der Erstellung unserer Webserver-Anwendung befasst, in der RESTful api implementiert ist, und es ist uns gelungen, eine Flutter-App zu erstellen, mit der grundlegende CRUD-Funktionen mit PostgreSQL ausgeführt werden können.

Github

https://github.com/tattwei46/flutter_crud_postgresql

Wenn Sie diesen Artikel hilfreich und lehrreich finden, geben Sie ihm etwas, um mich zu ermutigen, in Zukunft mehr davon zu schreiben

The Flutter Pub ist eine Medienpublikation, die Ihnen die neuesten und erstaunlichsten Ressourcen wie Artikel, Videos, Codes, Podcasts usw. zu dieser großartigen Technologie bietet, um Ihnen beizubringen, wie Sie damit schöne Apps erstellen. Sie können uns auf Facebook, Twitter und Medium finden oder hier mehr über uns erfahren. Wir würden uns freuen, eine Verbindung herzustellen! Und wenn Sie ein Schriftsteller sind, der Interesse daran hat, für uns zu schreiben, können Sie dies anhand dieser Richtlinien tun.