I have built the following using a combination of several examples and cannot get the results to display. This is my first attempt at using flutter/dart for a macos app so there are probably many mistakes. I am using the API demo at http://dummy.restapiexample.com/ and https://app.quicktype.io/ to generate the parsing logic.
The error I get in the app is:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<Data>'
In the app I enter the name Joe and the age 32. I can see from the debug output that the http.post is working correctly:
flutter: {status: success, data: {name: Joe, salary: 123, age: 32, id: 95}}
main.dart
import 'package:flutter/material.dart';
import 'package:apitestapp/widgets/ApiTest.dart';
var text = TextEditingController();
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool pressed = false;
final myController1 = TextEditingController();
final myController2 = TextEditingController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ApiTest',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('ApiTest'),
),
body:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: myController1,
decoration: InputDecoration(
hintText: 'Enter your name',
hintStyle: TextStyle(color: Colors.grey)
),
),
TextField(
controller: myController2,
decoration: InputDecoration(
hintText: 'Enter your age',
hintStyle: TextStyle(color: Colors.grey)
),
),
RaisedButton(
child: Text('Get ApiTest Data'),
onPressed: () {
nameTest = myController1.text;
ageTest = myController2.text;
print("Data sent: Name is $nameTest and age is $ageTest");
setState(() {
pressed = true;
});
},
),
ApiTest(),
],
),
),
);
}
}
ApiTest.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
String nameTest = "";
String ageTest = "";
// From https://app.quicktype.io/
Welcome welcomeFromJson(String str) => Welcome.fromJson(json.decode(str));
String welcomeToJson(Welcome data) => json.encode(data.toJson());
class Welcome {
String status;
Data data;
Welcome({
this.status,
this.data,
});
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
status: json["status"],
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": data.toJson(),
};
}
class Data {
String name;
String salary;
String age;
String id;
Data({
this.name,
this.salary,
this.age,
this.id,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
name: json["name"],
salary: json["salary"],
age: json["age"],
id: json["id"],
);
Map<String, dynamic> toJson() => {
"name": name,
"salary": salary,
"age": age,
"id": id,
};
}
class ApiTest extends StatefulWidget {
ApiTest({Key key}) : super(key: key);
@override
_ApiTestState createState() => _ApiTestState();
}
class _ApiTestState extends State<ApiTest> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Data>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Row(
children: [
Text(snapshot.data.name),
Text(snapshot.data.age),
],
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
);
}
Future<Data> fetchPost() async {
var url = "http://dummy.restapiexample.com/api/v1/create";
var body = json.encode({"name":"$nameTest","salary":"123","age":"$ageTest"});
Map<String,String> headers = {
'Content-type' : 'application/json',
'Accept': 'application/json',
};
final response = await http.post(url, body: body, headers: headers);
final responseJson = json.decode(response.body);
print(responseJson);
return responseJson;
}
}
Thanks for any help.
