Home > Back-end >  Future<dynamic>' is not a subtype of type 'Stream<List<dynamic>>
Future<dynamic>' is not a subtype of type 'Stream<List<dynamic>>

Time:09-28

I am trying to fetch the data from API using StreamBuilder, Kindly help with this error

Future<dynamic>' is not a subtype of type 'Stream<List<dynamic>>.

Basically we are fetching data and displaying data with help of ListView.buider and StreamBuilder:

Search_product.dart

import 'dart:async';

import 'package:beauty/user.dart';
import 'package:flutter/material.dart';
import 'package:beauty/backend.dart';

class SearchProduct extends StatefulWidget {
  @override
  _SearchProductState createState() => _SearchProductState();
}

class _SearchProductState extends State<SearchProduct> {
  List<Welcome> _welcome;
  Backend backend = new Backend();
  bool waiting = true;
  Stream _stream;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    Backend.getData().then((welcome) {
      setState(() {
        _welcome = welcome;
        waiting = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Color(0xFFEBEAEF),
        appBar: AppBar(
          title: Row(children: [
            SizedBox(
              width: 70.0,
            ),
            Text(
              'Search Product',
              style: TextStyle(
                color: Colors.black,
              ),
            ),
            SizedBox(
              width: 70.0,
            ),
            Flexible(
              child: CircleAvatar(
                child: Image.asset('assets/her.png'),
              ),
            ),
          ]),
          leading: IconButton(
            icon: Icon(
              Icons.arrow_back,
              color: Colors.black,
            ),
            onPressed: () {},
          ),
          backgroundColor: Color(0xFFEBEAEF),
        ),
        body: Column(children: [
          Container(
            color: Colors.white70,
            child: TextField(
              decoration: InputDecoration(
                prefixIcon: Icon(
                  Icons.search,
                  color: Colors.grey,
                ),
                hintText: 'Search  for product',
                contentPadding:
                    EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(12.0)),
                ),
                enabledBorder: OutlineInputBorder(
                  borderSide: BorderSide(color: Colors.white70, width: 1.0),
                  borderRadius: BorderRadius.all(Radius.circular(12.0)),
                ),
                focusedBorder: OutlineInputBorder(
                  borderSide: BorderSide(color: Colors.white70, width: 2.0),
                  borderRadius: BorderRadius.all(Radius.circular(12.0)),
                ),
              ),
              style: TextStyle(color: Colors.black),
            ),
          ),
          Container(
            child: waiting
                ? SizedBox(
                    width: 50,
                    height: 50,
                    child: CircularProgressIndicator(),
                  )
                : Expanded(
                    child: StreamBuilder(
                        stream: Backend.getData(),
                        builder: (BuildContext context,
                            AsyncSnapshot<List<dynamic>> snapshot) {
                          return ListView.builder(
                              padding: EdgeInsets.all(8),
                              itemCount: null == _welcome ? 0 : _welcome.length,
                              itemBuilder: (BuildContext context, int index) {
                                Welcome welcome = _welcome[index];
                                return Card(
                                  child: Column(
                                    children: <Widget>[
                                      ListTile(
                                        leading: CircleAvatar(
                                          radius: 30,
                                          backgroundImage: NetworkImage(snapshot
                                              .data[index].welcome.image),
                                        ),
                                        title: Text(
                                            snapshot.data[index].welcome.title),
                                        subtitle: Text(snapshot
                                            .data[index].welcome.description),
                                        trailing: Text(snapshot
                                            .data[index].welcome.price
                                            .toString()),
                                      )
                                    ],
                                  ),
                                );
                              });
                        }),
                  ),
          ),
        ]));
  }
}

Backend.dart

import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:beauty/user.dart';

class Backend {
  static getData() async {
    try {
      var url = Uri.parse('https://fakestoreapi.com/products');
      var response = await http.get(url);
      if (response.statusCode == 200) {
        return welcomeFromJson(response.body);
      } else {
        List error_message = ['error'];
        return error_message;
      }
    } catch (e) {
      print(e);
    }
  }
}

user.dart

    import 'dart:convert';

    
    List<Welcome> welcomeFromJson(String str) =>
        List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));
    
    String welcomeToJson(List<Welcome> data) =>
        json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
    
    class Welcome {
      Welcome({
        this.id,
        this.title,
        this.price,
        this.description,
        this.category,
        this.image,
        this.rating,
      });
    
      int id;
      String title;
      double price;
      String description;
      Category category;
      String image;
      Rating rating;
    
      factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
            id: json["id"],
            title: json["title"],
            price: json["price"].toDouble(),
            description: json["description"],
            category: categoryValues.map[json["category"]],
            image: json["image"],
            rating: Rating.fromJson(json["rating"]),
          );
    
      Map<String, dynamic> toJson() => {
            "id": id,
            "title": title,
            "price": price,
            "description": description,
            "category": categoryValues.reverse[category],
            "image": image,
            "rating": rating.toJson(),
          };
    }
    
    enum Category { MEN_S_CLOTHING, JEWELERY, ELECTRONICS, WOMEN_S_CLOTHING }
    
    final categoryValues = EnumValues({
      "electronics": Category.ELECTRONICS,
      "jewelery": Category.JEWELERY,
      "men's clothing": Category.MEN_S_CLOTHING,
      "women's clothing": Category.WOMEN_S_CLOTHING
    });
    
    class Rating {
      Rating({
        this.rate,
        this.count,
      });
    
      double rate;
      dynamic count;
    
      factory Rating.fromJson(Map<String, dynamic> json) => Rating(
            rate: json["rate"].toDouble(),
            count: json["count"],
          );
    
      Map<String, dynamic> toJson() => {
            "rate": rate,
            "count": count,
          };
    }
    
    class EnumValues<T> {
      Map<String, T> map;
      Map<T, String> reverseMap;
    
      EnumValues(this.map);
    
      Map<T, String> get reverse {
        if (reverseMap == null) {
          reverseMap = map.map((k, v) => new MapEntry(v, k));
        }
        return reverseMap;
      }
    }

CodePudding user response:

The response type from Backend.getData is a Future, not a Stream.

Replace

StreamBuilder(
  stream: Backend.getData(),
  builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {

with

FutureBuilder(
  future: Backend.getData(),
  builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
    //show visual loading
    if(!snapshot.hasData) return Center(child: CircularProgressIndicator());

CodePudding user response:

I think that the error may be caused by the getData function where you are returning a Future<dynamic> (because you do not specify any return type) and passing this output to the StreamBuilder initializer as stream parameter that requires a Stream type. Note also that the getData function is an async function so to get any output you need to await for it.

  • Related