Reputation: 109
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
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
Reputation: 1821
You have two options;
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
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