how to post form data request using flutter in http package - flutter

I want to send form data in flutter using the HTTP package. Getting the error:FormatException: Unexpected character (at character 1)
I/flutter (30465):
I am sending the form data in the HTTP post request.
Future<void> authethicate(
String schoolName,
String password,
) async {
try {
final url = 'https://yobimx.com/citykey/api/users/login';
final response = await http.post(url, body: {
'email': 'usamashafiq199#outlook.com',
'password': '123',
}, headers: {
"Content-Type": "application/x-www-form-urlencoded",
});
print(
json.decode(response.body),
);
final responseData = json.decode(response.body);
} catch (error) {
print(error);
}
}

I have to use a multipart request for request. Thanks for your help.
Future<void> authethicate(
String schoolName,
String password,
) async {
try {
final url = Uri.parse('https://yobimx.com/citykey/api/users/login');
Map<String, String> requestBody = <String, String>{
'email': 'usamashafiq199#outlook.com',
'password': '123'
};
var request = http.MultipartRequest('POST', url)
..fields.addAll(requestBody);
var response = await request.send();
final respStr = await response.stream.bytesToString();
print(
jsonDecode(respStr),
);
print("This is the Status Code$respStr");
var encoded = json.decode(respStr);
print(encoded['status']);
print('This is the userId${encoded['data']['user_id']}');
} catch (error) {
print(error);
}
}

Related

Retrieving data from http web call in flutter into a list object always empty

List is always empty even though body has contents. I am new to flutter so bare with me if this is basic. I am wanting to get back a list of station data I am coming from a c# background so forgive me if am missing something simple the test string body has the items and can see the items when i debug
class HttpService {
final String url = "url hidden";
final String host = 'url hidden';
final String apiSegment = "api/";
// ignore: non_constant_identifier_names
void login(email, password) async {
try {
Map<String, String> body = {
'username': email,
'password': password,
};
Map<String, String> headers = {'Content-Type': 'application/json'};
final msg = jsonEncode(body);
Response response =
await post(Uri.parse("$url/Login"), headers: headers, body: msg);
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data['jwtToken']);
print('Login successfully');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('jwtToken', data['jwtToken']);
List<Stations> stationData = await getStationData('11');
var test = stationData;
} else {
print('failed');
}
} catch (e) {
print(e.toString());
}
}
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
List<Stations> stationData = <Stations>[];
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
var body2 = body.toString();
stationData = body
.map(
(dynamic item) => Stations.fromJson(item),
)
.toList();
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
print(e.toString());
}
return stationData;
}
}
I am calling my function from the same class
List<Stations> stationData = await getStationData('11');
Data from body
Actually the problem is you are returning the data after the end of try catch.
Try this
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
final stationData = List<Stations>.from(body.map((item) => Stations.fromJson(item))); // made some changes
return stationData;
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
rethrow;
}
}
I hope this will help you

Flutter multipart image no sending with the rest of the body

I'm trying to send a multipart request using the flutter http package and so far, every field is sent successfully, except the image. The code is below.
Future multipartPostRequestProfile(
id, dob, country, state, gender, File? imgPath) async {
var token = await storage.read(key: 'jwt');
var request = http.MultipartRequest(
'PUT', Uri.parse('url'));
request.files.add(await http.MultipartFile.fromPath(
"image",
imgPath!.path,
));
request.fields['dateOfBirth'] = dob;
request.fields['country'] = country;
request.fields['state'] = state;
request.fields['gender'] = gender;
request.headers.addAll({
"Content-Type": "multipart/form-data",
"Authorization": "Bearer $token"
});
var res = await request.send();
var result = await http.Response.fromStream(res);
if (result.statusCode != 200)
return {'result': result.statusCode, 'body': result.body};
final Map<String, dynamic> responseData = jsonDecode(result.body);
return responseData;
}
try this..method
Future multipartRequestPost(
String url,
String methodName, {
required Map<String, String> header,
File? image1,
File? image2,
Map<String, String>? body,
String? image1Key,
String? image2Key,
}) async {
var client = http.Client();
try {
String fullURL = APIUrl.baseUrl + url;
var request = http.MultipartRequest(methodName,
Uri.parse(fullURL));
if (body != null) {
request.fields.addAll(body);
}
if (image1?.path.isNotEmpty ?? false) {
request.files.add(await http.MultipartFile.fromPath(image1Key ?? '',
image1?.path ?? ''));
request.files.add(await http.MultipartFile.fromPath(image2Key ??
'', image2?.path ?? ''));
}
request.headers.addAll(header);
http.StreamedResponse response = await request.send();
final respStr = await response.stream.bytesToString();
if (response.statusCode == 200 || response.statusCode == 201) {
return response.statusCode;
}
}
catch (exception) {
client.close();
throw AppException.exceptionHandler(exception);
}
}

fetching the response from API and dealing with the errors / converting Bytestreem to Map in flutter

I am trying to communicate with a PHP backend using API but I can not reach the body of the response.
I got the base code from the postman.
And here is the data of the body response:
I need to reach the message, and the errors to show them in the UI, the problem is response.stream it's type is Bytestreem and I can not convert it to Map
My code:
Future<void> _authenticateUp(String email, String password,
String passwordconfirmation, String username, String name,
{String phonenumber}) async {
var headers = {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
};
var request = http.MultipartRequest('POST', Uri.parse('$siteUrl/register'));
request.fields.addAll({
'email': email,
'password': password,
'password_confirmation': passwordconfirmation,
'username': username,
'name': name,
'phone_number': phonenumber
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
try {
if (response.statusCode == 200) {
await response.stream.bytesToString().then((value) {
print(value);
});
} else {
// here I want to print the message and the errors
}
} catch (e) {
throw e;
}
}
Add this As for Error your statusCode is not 200
try {
if (response.statusCode == 200) {
await response.stream.bytesToString().then((value) {
print(value);
});
} else {
await response.stream.bytesToString().then((value) {
print(value);
var jsonResponse = json.decode(response.body.toString());
var nameError = jsonResponse["errors"]["name"][0];
var emailError = jsonResponse["errors"]["email"][0];
var usernameError = jsonResponse["errors"]["username"][0];
var passwordError = jsonResponse["errors"]["password"][0];
//now can print any print(emailError);
});
}

Register to aqueduct backend from Flutter frontend

I'm having a bit of difficulty with registering to aqueduct backend from my Flutter frontend
Here is my code in my frontend:
Future<void> signUp(String email, String password) async {
final body = "username:$email,password:$password"; //<- return request entity could not be decoded
//final body = {"username": email, "password": password}; //<- return bad state: Cannot set the body fields of Request with content-type "application/json"
try {
final http.Response response = await http.post(
"http://localhost:8888/register",
headers: {"Content-Type": "application/json"},
body: body);
final jsonResponse = json.decode(response.body);
if (jsonResponse["error"] != null) {
throw HttpException(jsonResponse["error"]);
}
} catch (error) {
throw error;
}
}
There must be some silly mistake. I believe it is with formatting body so I tried 2 options and both throw different http exception (as in comment).
Here is an example of connecting to an Aqueduct server from a Flutter client. (This isn't really a server question, though, since the client and server are independent of each other.)
Here is an example of registering:
void _register(String email, String password) async {
Map<String, String> headers = {"Content-type": "application/json"};
final jsonString = '{"username":"$email", "password":"$password"}';
Response response = await post(YOUR_URL_HERE, headers: headers, body: jsonString);
print('${response.statusCode} ${response.body}');
}
In your example you aren't encoding the JSON correctly.
And here is another example of signing in. The class is a view model architecture that I talk about here.
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
class LoginViewModel extends ChangeNotifier {
String _token = '';
bool _isLoggedIn = false;
bool get isLoggedIn => _isLoggedIn;
String get token => _token;
Future onLoginPressed(String username, String password) async {
if (username.isEmpty || password.isEmpty) {
return;
}
_isLoggedIn = await _login(username, password);
notifyListeners();
}
Future<bool> _login(String username, String password) async {
var clientID = 'com.example.app';
var clientSecret = '';
var body = 'username=$username&password=$password&grant_type=password';
var clientCredentials = Base64Encoder().convert('$clientID:$clientSecret'.codeUnits);
Map<String, String> headers = {
'Content-type': 'application/x-www-form-urlencoded',
'authorization': 'Basic $clientCredentials'
};
var response = await http.post(YOUR_URL_HERE, headers: headers, body: body);
final responseBody = response.body;
if (response.statusCode != 200) {
return false;
}
final map = json.decode(responseBody);
_token = map['access_token'];
return true;
}
}

How to set headers for POST with flutter and Dio

this is my code below, i'm stuck please help.
void getProducts() async {
String htoken = Utils.prefs.getString("token");
print(htoken);
try {
var dio = Dio(BaseOptions(headers: {"appusertoken": "$htoken"}));
//dio.options.headers["appusertoken"] = "$htoken";
Response response = await dio.post(
'APIURL',
);
print("data coming");
print(response.data);
} on DioError catch (e) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
}
}
it was throwing an error of data null.
I was able to fix the issues.
Add optional parameter options for dio.post method and define headers with Options class:
void getProducts() async {
String htoken = Utils.prefs.getString("token");
try {
Dio dio = Dio();
Response response = await dio.post("http://URL",
data: {},
options: Options(
headers: {"appusertoken": "$htoken"},
));
print("data coming");
print(response);
} on DioError catch (e) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
}
}
For example :
Dio _dio = new Dio();
_dio.options.contentType = Headers.formUrlEncodedContentType;
_dio.options.headers['Authorization'] = 'bearer $authToken';
or use :
final Map<String, dynamic> header = {'Authorization': 'bearer $authToken'};
enter code here
final responseData = await _dio.get(
Apis.account_profit,
options: RequestOptions(
method: 'GET', headers: header, baseUrl: Apis.apiBaseUrl),
);