Flutter provider fetch data, E-Com app 6

How does the provider in Flutter fetch data and we display them? That’s our first concern as we’ve been building the e-commerce app.

First thing first.

Firstly, we need the Provider package dependency. Therefore let’s add the dependency to the pubspec.yaml file.

Secondly, make sure the package is the latest.

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  provider: ^6.0.3
  material_color_utilities: ^0.1.4  
  dynamic_color: ^1.1.2
  google_fonts: ^2.3.1

Finally the most important thing is that we need a model class where we have declared the items. It might be a private property, but we need to make it public.

import 'package:flutter/material.dart';

import 'product.dart';

class Products with ChangeNotifier {
  final List<Product> _items = [
    Product(
      id: 'p1',
      title: 'Smart Phone',
      description: 'A Smart Phone - get big Discount!',
      price: 29.99,
      imageUrl:
          'https://cdn.pixabay.com/photo/2015/12/13/16/02/ios-1091302_960_720.jpg',
    ),
    Product(
      id: 'p2',
      title: 'Smart TV',
      description: 'A Smart TV.',
      price: 59.99,
      imageUrl:
          'https://cdn.pixabay.com/photo/2015/02/07/20/58/tv-627876_960_720.jpg',
    ),
....
List<Product> get items {
    return [..._items];
  }

  Product findById(String id) {
    return _items.firstWhere((prod) => prod.id == id);
  }
...
//code is incomplete for brevity, please see the GitHub Repository

Certainly, we need a class constructor. 

So that we can pass the data.

class Product {
  final String id;
  final String title;
  final String description;
  final double price;
  final String imageUrl;
  bool isFavorite;

  Product({
    required this.id,
    required this.title,
    required this.description,
    required this.price,
    required this.imageUrl,
    this.isFavorite = false,
  });
}

It’s always better to use a GridView builder constructor so that we can maintain the context. Right?

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../models/products.dart';
import './product_item.dart';

/// seven
///

class ProductsGrid extends StatelessWidget {
  const ProductsGrid({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<Products>(context);
    final products = productsData.items;
    return GridView.builder(
      padding: const EdgeInsets.all(10.0),
      itemCount: products.length,
      itemBuilder: (ctx, i) => ProductItem(
        products[i].id,
        products[i].title,
        products[i].imageUrl,
      ),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: 3 / 2,
        crossAxisSpacing: 10,
        mainAxisSpacing: 10,
      ),
    );
  }
}

To get all the products in one place we have a products class that uses mixins with ChangeNotifier.

It has mainly one purpose. 

We can get all the products at any time. On the other hand, we can also get any particular product by its ID.

Similarly we can now use the product detail screen to tap the ID of the product using the Provider package.

We have got the particular product ID using the Modal Route class.

With the help of this class, we can get the ID. 

However, before that we have got all the products through the class constructor.

import 'package:flutter/material.dart';

import '../views/product_detail_screen.dart';

class ProductItem extends StatelessWidget {
  final String id;
  final String title;
  final String imageUrl;

  const ProductItem(
    this.id,
    this.title,
    this.imageUrl,
  );

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: GridTile(
        footer: GridTileBar(
          backgroundColor: Colors.yellow.shade900,
          leading: IconButton(
            icon: const Icon(Icons.favorite),
            color: Theme.of(context).colorScheme.onSecondary,
            onPressed: () {},
          ),
          title: Text(
            title,
            textAlign: TextAlign.center,
          ),
          trailing: IconButton(
            icon: Icon(
              Icons.shopping_cart,
              color: Theme.of(context).colorScheme.onPrimary,
            ),
            onPressed: () {},
            color: Theme.of(context).colorScheme.secondary,
          ),
        ),
        child: GestureDetector(
          onTap: () {
            Navigator.of(context).pushNamed(
              ProductDetailScreen.routeName,
              arguments: id,
            );
          },
          child: Image.network(
            imageUrl,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

In our previous discussion we have seen how we can use the Modal Route class to send the ID of the products. 

But at the very beginning we need all the data in one place.

Managing the Flutter backend and controlling the color
Managing the Flutter back-end and controlling the colour

As a result we can tap any one of the items to reach the detail page which we have discussed before.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Flutter, Dart and Algorithm

Twitter


Posted

in

, , ,

by

Comments

4 responses to “Flutter provider fetch data, E-Com app 6”

  1. […] long as we just display the products through the ChangeNotifierProvider create method, we can pass around the data. But how can we change the state of any individual product […]

  2. […] In that case, the show favorite icon of pop up menu button will display a blank page. […]

  3. […] Most importantly, we have learned how to display product items by using the Provider package. […]

  4. […] we have added the products and provided the products with the help of the Provider […]

Leave a Reply