Geting data from mysql to StreamBuilder Flutter

3,544

Solution 1

If you want to use it periodically with StreamBuilder;

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  StreamController _streamController = StreamController();
  Timer _timer;

  Future getData() async {
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);
    var data = jsonDecode(response.body);

    //Add your data to stream
    _streamController.add(data);
  }

  @override
  void initState() {
    getData();

    //Check the server every 5 seconds
    _timer = Timer.periodic(Duration(seconds: 5), (timer) => getData());

    super.initState();
  }

  @override
  void dispose() {
    //cancel the timer
    if (_timer.isActive) _timer.cancel();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: StreamBuilder(
        stream: _streamController.stream,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData)
            return ListView(
              children: snapshot.data.map((document) {
                return ListTile(
                  title: Text(document['title']),
                  subtitle: Text(document['type']),
                );
              }).toList(),
            );
          return Text('Loading...');
        },
      ),
    );
  }
}

Solution 2

You should use FutureBuilder instead of StreamBuilder. You don't need to use StreamBuilder for fetching data from the server, If you don't want to check server periodically. (If you want to use it periodically and with StreamBuilder check my next answer);

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Server',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: MyHomePage(title: 'Flutter Server App'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future getData() async {
    var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
    http.Response response = await http.get(url);
    var data = jsonDecode(response.body);
    return data;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: FutureBuilder(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData)
            return ListView(
              children: snapshot.data.map((document) {
                return ListTile(
                  title: Text(document['title']),
                  subtitle: Text(document['type']),
                );
              }).toList(),
            );
          return Text('Loading...');
        },
      ),
    );
  }
}
Share:
3,544
Maen Al Nassan
Author by

Maen Al Nassan

Updated on December 19, 2022

Comments

  • Maen Al Nassan
    Maen Al Nassan over 1 year

    I have an assignment and I have to take data from mysql server into a flutter and pass it to StreamBuilder and I was trying to use the same class we are using it in firebase and now I have problem with passing the data that I already take it from the server into the StreamBuilder and as I remember I have to use a different type of snapshot, any help.

    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Server',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.pink,
          ),
          home: MyHomePage(title: 'Flutter Server App'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      get documents => null;
    
    
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
            centerTitle: true,
          ),
        );
      }
    
      Future getData() async{
        var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
        http.Response response = await http.get(url);
        var data = jsonDecode(response.body);
        print(data.toString());
    
    
      }
    
      @override
      void initState() {
        getData();
      }
    }
    
    class BookList extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new StreamBuilder(
          stream: _MyHomePageState.getData().snapshot(),
          builder: (BuildContext context, AsyncSnapshot<_MyHomePageState> snapshot) {
            if (snapshot.hasData) return new Text('Loading...');
            return new ListView(
              children: snapshot.data.documents.map((document) {
                return new ListTile(
                  title: new Text(document['title']),
                  subtitle: new Text(document['type']),
                );
              }).toList(),
            );
          },
    
        );
    
      }
    
    }
    

    The new code is this

    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    import 'dart:async';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Server',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.pink,
          ),
          home: MyHomePage(title: 'Flutter Server App'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      StreamController _streamController = StreamController();
      Timer _timer;
      var data;
    
      Future getData() async {
        var url = 'https://milk-white-reveille.000webhostapp.com/get.php';
        http.Response response = await http.get(url);
    
    
        String jsonsDataString = response.body.toString(); // toString of Response's body is assigned to jsonDataString
        data = jsonDecode(jsonsDataString);
        print(data.toString());
        //Add your data to stream
        _streamController.add(data);
      }
    
      @override
      void initState() {
        getData();
    
        //Check the server every 5 seconds
        _timer = Timer.periodic(Duration(seconds: 5), (timer) => getData());
    
        super.initState();
      }
    
      @override
      void dispose() {
        //cancel the timer
        if (_timer.isActive) _timer.cancel();
    
        super.dispose();
      }
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Home"),
          ),
          body: new _MySql()
    
              );
    
      }
    }
    
    
    
    class _MySql extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: StreamBuilder(
            stream: _MyHomePageState()._streamController.stream,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasData)
                return ListView(
                  children: snapshot.data((data) {
                    return ListTile(
                      title: Text(data['title']),
                      subtitle: Text(data['type']),
                    );
                  }).toList(),
                );
              return CircularProgressIndicator();
            },
          ),
        );
      }
    }
    

    but on the phone screen loading... appearing this one from terminal E/flutter (10194): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Unexpected character (at character 1) E/flutter (10194): connected{"title":"maen","type":"dev"}