I am newbie of flutter
I want to load some data from my restful API by using Yii2
Provide data to API: { "account":"B0929036", "password":"12344567" }
........(more account and password)
API return data: [ { "access_token":"bugeywbhihwiuvwhe",//garbled "ip_address":"172.150.111.122", "password_hash":"gjwhubehbhfyuqbh$gy$iknb$oknwun"//garbled } ]
API post request and Model:
import 'dart:convert';
// import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
class LoginModel {
final String accessToken;
final String ipAddress;
const LoginModel({required this.accessToken, required this.ipAddress});
factory LoginModel.fromJson(Map<String, dynamic> json) {
return LoginModel(
//API return
accessToken: json['access_token'],
ipAddress: json['ip_address'],
);
}
}
Future<LoginModel> createLogin(String account, String password) async {
final response = await http.post(
Uri.parse(
'http://120.126.16.222/gardeners/login'), //'https://jsonplaceholder.typicode.com/users'
headers: <String, String>{'Content-Type': 'application/json;charset=UTF-8'},
body: jsonEncode(<String, String>{
//input
'account': account,
'password': password,
}),
);
if (response.statusCode == 200) {
return LoginModel.fromJson(response.body as Map<String, dynamic>);
} else {
throw Exception('${response.reasonPhrase},${response.statusCode}');
}
}
API will return like this:API return data
login_post.dart
import 'package:test_spi/models/post_test.dart';
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final TextEditingController _accountcontroller = TextEditingController();
final TextEditingController _passwordcontroller = TextEditingController();
Future<LoginModel>? _futureLogin;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Gardeners Login Data(Post) Post'),
),
body: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8),
child: (_futureLogin == null) ? buildColumn() : buildFutureBuilder(),
),
);
}
Column buildColumn() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 300,
height: 80,
child: TextField(
controller: _accountcontroller,
decoration: const InputDecoration(
hintText: 'Enter Account',
labelText: "帳號",
prefixIcon: Icon(Icons.person),
),
),
),
SizedBox(
width: 300,
height: 80,
child: TextField(
controller: _passwordcontroller,
obscureText: true,
decoration: const InputDecoration(
hintText: 'Enter Password',
labelText: "密碼",
prefixIcon: Icon(Icons.lock),
),
),
),
SizedBox(
width: 150,
height: 48,
child: ElevatedButton(
onPressed: () {
setState(() {
_futureLogin = createLogin(
_accountcontroller.text, _passwordcontroller.text);
});
},
child: const Text('Show'),
),
),
],
);
}
FutureBuilder<LoginModel> buildFutureBuilder() {
return FutureBuilder<LoginModel>(
future: _futureLogin,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasData) {
return ListView(
padding: const EdgeInsets.all(20),
children: <Widget>[
Text(
'Access Token:${snapshot.data!.accessToken}',
),
Text(
'IP Address: ${snapshot.data!.ipAddress}',
),
],
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
} else {
return const Text('No data available');
}
},
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:test_spi/homepage.dart';
import 'package:test_spi/login_post.dart';
void main()
{
runApp(const MyApp());
}
class MyApp extends StatelessWidget
{
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context)
{
return MaterialApp
(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const LoginPage(),
);
}
}
Error just like this,after i enter the account and password into TextField,press the button,it should be refresh and print what i want(which are access_token and ip_address).
However,
1.when i set the response.statuscode==201
output Expection: OK,200
which means successfully connected, but didn't appear any data
2.when i set the response.statuscode==200
output Expected a value of type 'Map<String,dynamic>',but got one of type 'String'
Here are the demo page:
For 1. input For 1. input
For 1. output For 1. output
For 2. input For 2. input
For 2. output For 2. output
Any ideas what I am doing wrong? Which parts should I improve? Thanks in advance!