Jon
Jon

Reputation: 109

How to get data object in flutter

I have JSON data like this:

{
    "iduser": 3,
    "fname": "joni"
}

I want to display it on the home page.

Previously I have created a model class below:

usermodel.dart

class UserModel {
  int id;
  String fname;

  UserModel(
    this.id,
    this.fname,
  );

  UserModel.fromJson(Map<String, dynamic> response) {
    id = response['iduser'];
    fname = response['fname'];
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'fname': fname,
    };
  }
}

and I created a service page to interact with API

class AuthService {
  String baseUrl = 'https://myurl.com';
  Future<UserModel> getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var id = prefs.getInt('id');
    var token = prefs.getString('token');
    var url = '$baseUrl/users/$id';
    var headers = {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token'
    };

    var response = await http.get(
      Uri.parse(url),
      headers: headers,
    );

    print(response.body);

    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      UserModel user = UserModel.fromJson(data);
      return user;
    } else {
      print(response.body);
      throw Exception('Failed');
    }
  }
}

home.dart

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Center(
        child: Text( ), //get json fname
      ),
    );
  }
}

before I run but I get error type:

'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<List>'

How to display the fname I get from the service on the home page?

Upvotes: 0

Views: 7178

Answers (3)

FpB
FpB

Reputation: 325

First, you may want to be consistent in your map key to get the desired result.

You have to replace the key of flutter map version from:

id = response['id']; => id = response['iduser'];

or vice versa.

Now in your homepage, you need to instantiate the AuthService class in order to access the function that will get the specified user.

You need to use FutureBuilder in order to automatically update the Text if the data was fetched.

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    AuthService _authService = AuthService();
    return Container(
      color: Colors.white,
      child: FutureBuilder<User>(
        future: _authService.getUser(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Text(snapshot.data.firstName);
          }
          /// Show some loading artifact while fetching the
          /// user data from the server.
          else {
            return CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

Upvotes: 0

Salih Can
Salih Can

Reputation: 1821

You have two options;

  1. Use FutureBuilder
  2. Convert to StatefullWidget

I give you FutureBuilder example;

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<UserModel>(
      future: AuthService().getUser(),
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.waiting: return Text('Loading....');
          default:
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              final data = snapshot.data;
              return Container(
                color: Colors.white,
                child: Center(
                  child: Text(data.fname), //get json fname
                ),
              );
            }
        }

      },
    );
  }
}

Also, as far as I can see, there is a problem with the id conversion of the fromJson and toJson methods. Related fields should be 'iduser' according to json data.

class UserModel {
  int id;
  String fname;

  UserModel(
    this.id,
    this.fname,
  );

  UserModel.fromJson(Map<String, dynamic> response) {
    id = response['iduser'];
    fname = response['fname'];
  }

  Map<String, dynamic> toJson() {
    return {
      'iduser': id,
      'fname': fname,
    };
  }
}

Upvotes: 1

sid
sid

Reputation: 437

Make home.dart a stateful widget and get the data in initstate and store in a variable. Use that variable to display the data here is how


class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  void initState() {
    super.initState();
    getAsync();
  }

  UserModel user;
  getAsync() async {
    try {
      user = await AuthService().getUser();
    } catch (e) {
      print(e);
    }

    if (mounted) setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    if (user == null) return Center(child: CircularProgressIndicator());
    else
    return Container(
      color: Colors.white,
      child: Center(
        child: Text(user.fname), //get json fname
      ),
    );
  }
}

Upvotes: 3

Related Questions