Home > Blockchain >  how can I fetch data from async function in flutter?
how can I fetch data from async function in flutter?

Time:08-30

I'm creating a simple app that uses an api which returns my adress ip i'm trying to fetch my ip adress in the app but I got this error "type 'null' is not a subtype of type 'map String dynamic ' in type cast" can you help me please

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart';
void main() => runApp(MaterialApp(
    home: IP(),
    ));

class IP extends StatefulWidget {
  const IP({Key? key}) : super(key: key);

  @override
  State<IP> createState() => _IPState();
}

class _IPState extends State<IP> {

  Map data = {};

void getIp() async {
  Response response = await get(
  Uri.parse('https://api.ipify.org/?format=json'));
  Map data = jsonDecode(response.body);
  String ip = data['ip'];
  print(ip);
}

@override
  void initState() {
  super.initState();
  getIp();
  }

  @override
  Widget build(BuildContext context) {
    data = data.isNotEmpty ? data : ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;
    return  Scaffold(
      appBar: AppBar(
        title: Text('My IP adress is'),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.cyan,
      ),
      body: Center(
         child: Text('$data[ip]')
      )
    );
  }
}



CodePudding user response:

try this:

class _IPState extends State<IP> {
  

  Future<String> getIp() async {
    Response response =
        await get(Uri.parse('https://api.ipify.org/?format=json'));
    Map data = jsonDecode(response.body);
    return data['ip'];
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
   
    return Scaffold(
      appBar: AppBar(
        title: Text('My IP adress is'),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.cyan,
      ),
      body: FutureBuilder(
        future: getIp(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Text('Loading....');
            default:
              if (snapshot.hasError)
                return Text('Error: ${snapshot.error}');
              else
                return Center(child: Text('${snapshot.data}'));
          }
        },
      ),
    );
  }
}

enter image description here

CodePudding user response:

Wrap your function in a Future, your data hast to be collected first, then you can show the result when future is completed, otherwise show a loading circle.

class _IPState extends State<IP> {

  Future<Map> data;

  Future<Map> getIp() async {
    /// TODO: Get your future IP
  }

  @override
  void initState() {
    super.initState();
    getIp();
  }

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(
        title: Text('My IP adress is'),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.cyan,
      ),
      body: FutureBuilder(
         future: getIp(),
         builder: (_,snap){
               return snap.hasData ? CircleProgressIndicator() : Text(data[ip]);
            }
        )
    );
  }
}
  • Related