Reader small image

You're reading from  Flutter Cookbook, Second Edition - Second Edition

Product typeBook
Published inMay 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781803245430
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Simone Alessandria
Simone Alessandria
author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria

Right arrow

Technical requirements

  1. To follow along with the recipes in this chapter, you should have the following software installed on your Windows, Mac, Linux, or Chrome OS device:
  2. The Flutter SDK.
  3. The Android SDK, when developing for Android.
  4. macOS and Xcode, when developing for iOS.
  5. An emulator or simulator, or a connected mobile device enabled for debugging.
  6. An internet connection to use web services.
  7. Your favorite code editor. Android Studio, Visual Studio Code, and IntelliJ IDEA are recommended. All should have the Flutter/Dart extensions installed.

You'll find the code for the recipes in this chapter on GitHub at https://github.com/PacktPublishing/Flutter-Cookbook/tree/master/chapter_08.

Converting Dart models into JSON

JSON has become the standard format for storing, transporting, and sharing data between applications: several web services and databases use JSON to receive and serve data. Later in this chapter, we will learn how to store data in a device, but in this recipe, we will learn how to serialize (or encode) and deserialize (or decode) data structures from/to JSON.

  1. JSON stands for JavaScript Object Notation. Even if it largely follows JavaScript syntax, it can be used independently from Javascript. Most modern languages, including Dart, have methods to read and write JSON data.

The following screenshot shows an example of a JSON data structure:

  1. As you can see, JSON is a text-based format that describes data in key-value pairs: each object (a pizza, in this example) is included curly brackets. In the object, you can specify several properties or fields. The key is generally included in quotes; then, you put a colon, and then the value. All key-value pairs...

Handling JSON schemas that are incompatible with your models

In a perfect world, JSON data would always be 100% compatible with your Dart classes, so the code you completed in the previous recipe would be ready to go to production and never raise errors. But as you are fully aware, this world is far from perfect, and so is the data you are likely to deal with in your apps. That's why, in this recipe, you will learn how to transform your code and make it more solid and resilient, and hopefully production ready.

Getting ready

To follow along with this recipe, you need to do the following:

  1. Complete the previous recipe.
  2. Download a more real-world pizzalist_broken.json file at https://github.com/PacktPublishing/Flutter-Cookbook/tree/master/chapter_08.
  3. Rename the file to pizzalist.json

How to do it...

For this recipe, using the project we built in the previous recipe, we will deal with a real-world JSON file, available at https://github.com/PacktPublishing/Flutter-Cookbook/tree/master...

Catching common JSON errors

As you saw in the previous recipe, you need to deal with JSON data that may be incompatible with your own data. But there is another source of errors that comes from within your code.

  1. When dealing with JSON, it often happens that the key names are repeated several times in your code. Since we are not perfect, we might create an error by typing in something that's incorrect. It's rather difficult to handle these kinds of errors as they only occur at runtime.
  2. A common way to prevent these kinds of typos is to use constants instead of typing the key names each time you need to reference them.

Getting ready

To follow along with this recipe, you will need to have completed the previous recipe.

How to do it...

In this recipe, we will use constants instead of typing in the keys of each field of the JSON data. The starting code is at the end of the previous recipe:

  1. At the top of the pizza.dart file (before the Pizza class), add the constants...

Saving data simply with SharedPreferences

Among the several ways we can save data with Flutter, arguably one of the simplest is using SharedPreferences: it works for Android, iOS, the web and desktop, and it's great when you need to store simple data within your device.

  1. You shouldn't use shared_preferences for critical data as data stored there is not encrypted, and writes are not always guaranteed. On the other hand, it’s also rather reliable and suitable for most use cases.

At its core, SharedPreferences stores key-value pairs on disk. More specifically, only primitive data can be saved: numbers, Booleans, Strings and stringLists. All data is saved within the app.

  1. In this recipe, you will create a very simple app that keeps track of the number of times the user opened the app and allows the user to delete the record.

Getting ready

  1. To follow along with this recipe, you will need the starting code for this recipe at https://github.com/PacktPublishing/Flutter-Cookbook...

Accessing the filesystem, part 1 – path_provider

The first step whenever you need to write files to your device is knowing where to save those files. In this recipe, we will create an app that shows the current system's temporary and document directories.

  1. path_provider is a library that allows you to find common paths in your device, regardless of the operating system your app is running on. For example, on iOS and Android, the path of the document is different. By leveraging path_provider, you don't need to write two different methods based on the OS you are using; you just get the path by using the library's methods.
  2. The path_provider library currently supports Android, iOS, Windows, macOS, and Linux. Check out https://pub.dev/packages/path_provider for the updated OS support list.

Getting ready

To follow along with this recipe, you must create a new app or update the code from the previous recipe.

How to do it...

To use path_provider in your app, follow these...

Accessing the filesystem, part 2 – working with directories

  1. In this section, we'll build upon the previous recipe so that you can read and write to files using Dart's Directory class and the dart:io library.

Getting ready

To follow along with this recipe, you need to have completed the previous recipe.

How to do it...

In this recipe, we will:

  • Create a new file inside our device or simulator/emulator.
  • Write some text.
  • Read the content in the file and show it on the screen.

The beginning code for this recipe is the end of the previous one. The methods for reading and writing to files are included in the dart.io library. Follow these steps:

  1. At the top of the main.dart file, import the dart:io library:
import 'dart:io';
  1. At the top of the _MyHomePageState class, in the main.dart file, create two new State variables for the file and its content:
late File myFile;
String fileText='';
  • Still in the MyHomePageState class, create a new method...

Using secure storage to store data

  1. A very common task for apps is storing user credentials, or other sensitive data, within the app itself. SharedPreferences is not an ideal tool to perform this task as data cannot be encrypted. In this recipe, you will learn how to store encrypted data using flutter_secure_storage, which provides an easy and secure way to store data.

Getting ready

To follow along with this recipe, you will need to do the following:

  1. If you are using Android, you need to set the compileSdkVersion in your app's build.gradle file to 33. The file is located in your project folder, in /android/app/build.gradle. The compileSdkVersion key must be set in the defaultConfig node, like this:
compileSdkVersion 33
  1. Download the starting code for this app, which is available at https://github.com/PacktPublishing/Flutter-Cookbook/tree/master/chapter_08.

How to do it...

For this recipe, we will create an app that takes a String from a text field and stores it securely...

Designing an HTTP client and getting data

Most mobile apps rely on data that comes from an external source. Think of apps for reading books, watching movies, sharing pictures with your friends, reading the news, or writing emails: all these apps use data taken from an external source. When an app consumes external data, usually, there is a backend service that provides that data for the app: a web service or web API.

What happens is that your app (frontend or client) connects to a web service over HTTP and requests some data. The backend service then responds by sending the data to the app, usually in .json or .xml format.

For this recipe, we will create an app that reads and writes data from a web service. As creating a web API is beyond the scope of this book, we will use a mock service, called Wire Mock Cloud, that will simulate the behavior of a real web service, but will be extremely easy to set up and use. In a later chapter, you will also see another way of creating a real-world...

POST-ing data

In this recipe, you will learn how to perform a POST action on a web service. This is useful whenever you are connecting to web services that not only provide data but also allow you to change the information stored on the server-side. Usually, you will have to provide some form of authentication to the service, but for this recipe, as we are using a mock service, this will not be necessary.

Getting ready

  1. To follow along with this recipe, you need to have completed the code in the previous recipe.

How to do it...

To perform a POST action on a web service, follow these steps :

  • Log into the Mock Lab service at https://app.wiremock.cloud/ and click on the Stubs section of the example API. Then, create a new Stub.
  • Complete the request, as follows:

    • Name: Post Pizza
    • Verb: POST
    • Address: /pizza
    • Status: 201
    • Body type: json
    • Body: {"message": "The pizza was posted"}
  • Press the Save button.
  • In the Flutter project, in the httpHelper.dart file, in the HttpHelper...

PUT-ting data

In this recipe, you will learn how to perform a PUT action on a web service. This is useful when your apps need to edit existing data in a web service.

Getting ready

  1. To follow along with this recipe, you need to have completed the code in the previous recipe.

How to do it...

To perform a PUT action on a web service, follow these steps:

  • Log into the Wiremock service at https://app.wiremock.cloud and click on the Stubs section of the example API. Then, create a new Stub.
  • Complete the request, as follows:

    • Name: Put Pizza
    • Verb: PUT
    • Address: /pizza
    • Status: 200
    • Body Type: json
    • Body: {"message": "Pizza was updated"}
  • Click the “Save” button
  • In the Flutter project, add a putPizza method to the HttpHelper class in the http_helper.dart file:
  Future<String> putPizza(Pizza pizza) async {
    const putPath = '/pizza';
    String put = json.encode(pizza.toJson());
    Uri url = Uri.https(authority, putPath);
    http.Response...

DELETE-ing data

In this recipe, you will learn how to perform a DELETE action on a web service. This is useful when your apps need to delete existing data from a web service.

Getting ready

  1. To follow along with this recipe, you must have completed the code in the previous recipe.

How to do it...

To perform a DELETE action on a web service, follow these steps:

  1. Log into the Wiremock service at https://app.wiremock.cloud and click on the Stubs section of the example API. Then, create a new Stub.
  2. Complete the request, with the following data:
    • Name: Delete Pizza
    • Verb: DELETE
    • Address: /pizza
    • Status: 200
    • Bpdy Type: json
    • Body: {"message": "Pizza was deleted"}
  3. Save the new Stub
  • In the Flutter project, add a deletePizza method to the HttpHelper class in the http_helper.dart file:
Future<String> deletePizza(int id) async {
    const deletePath = '/pizza';
    Uri url = Uri.https(authority, deletePath);
    http.Response r = await http.delete(
     ...

DELETE-ing data

In this recipe, you will learn how to perform a DELETE action on a web service. This is useful when your apps need to delete existing data from a web service.

Getting ready

To follow along with this recipe, you must have completed the code in the previous recipe.

How to do it...

To perform a DELETE action on a web service, follow these steps:

  1. Log in to the Wiremock service at https://app.wiremock.cloud and click on the Stubs section of the example API. Then, create a new stub.
  2. Complete the request, with the following data:
    • Name: Delete Pizza
    • Verb: DELETE
    • Address: /pizza
    • Status: 200
    • Body Type: json
    • Body: {"message": "Pizza was deleted"}
  3. Save the new stub.
  4. In the Flutter project, add a deletePizza method to the HttpHelper class in the http_helper.dart file:
    Future<String> deletePizza(int id) async {
        const deletePath...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Flutter Cookbook, Second Edition - Second Edition
Published in: May 2023Publisher: PacktISBN-13: 9781803245430
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Simone Alessandria

Simone Alessandria wrote his first program when he was 12. It was a text-based fantasy game for the Commodore 64. Now, he is a trainer (MCT), author, speaker, passionate software architect, and always a proud coder. He is the founder and owner of Softwarehouseit. His mission is to help developers achieve more through training and mentoring. He has authored several books on Flutter, including Flutter Projects, published by Packt, and web courses on Pluralsight and Udemy.
Read more about Simone Alessandria