Error in fetching data from api in flutter - json

I have to fetch data from this api - https://api.wazirx.com/api/v2/market-status
I am getting "xmlhttprequest error"
how should I overcome this.
Future<void> fetchUserData() async {
final response = await http.get(Uri.https('api.wazirx.com', '/api/v2/market-status'));
if (response.statusCode == 200) {
print(response.body);
} else {
throw Exception("Request Rejected");
}
}

Try this.
add the headers 'Accept' : 'application/json'
Future<void> fetchUserData() async {
final host = 'api.wazirx.com';
final path = '/api/v2/market-status';
final headers = {'Accept': 'application/json'};
final uri = Uri.https(host, path);
final response = await http.get(uri, headers: headers);
if (response.statusCode == 200) {
print(response.body);
} else {
throw Exception("Request Rejected");
}
}

Related

Exception caught by image resource service ═ HTTP request failed, statusCode: 403,

I picked an image from my gallery, then use this image as in my http body parameter , I believe it sending the image in string format thats why its showing this error.How can I display this image in my App ?
I tried to implement with Multipart but didn't came up with any solution, so I stick to this base64 format
void filePicker() async {
final File? selectedImage =
await ImagePicker.pickImage(source: ImageSource.gallery);
print(selectedImage!.path);
setState(() {
image = selectedImage;
fileContent = image!.readAsBytesSync();
fileContentBase64 = base64.encode(fileContent);
print(fileContentBase64.substring(0, 100));
});
}
Then in my API function use this image with other parameters
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var response = await http.post(
Uri.parse(
"http://medbo.digitalicon.in/json/SaveCustomTestBooking"),
body: ({
'VisitDate': _selectedDate,
'EncUserId': EncUserId,
'UserFile': fileContentBase64 , // here
'Description': testTextController.text
}));
if (response.statusCode == 200) {
print("Correct");
print(response.body);
jsonResponse = json.decode(response.body.toString());
print(jsonResponse);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DieticianAfterDateSelectPage(
rresponse:
DieticianEncBookingIdModel.fromJson(jsonResponse),
)));
} else {
// ScaffoldMessenger.of(context)
// .showSnackBar(SnackBar(content: Text("Somthing went wrong")));
throw Exception("Faild to fetch");
}
}
}

How to pass image file to the body of Http request (POST) in Flutter?

I Took a variable in my State File? image;
Then Accesing image from my device
void filePicker() async {
final File? selectedImage =await ImagePicker.pickImage(source: ImageSource.gallery);
print(selectedImage!.path);
setState(() {
image = selectedImage;
});
}
Then tyring to pass the image file along with other http body parameters. If I didn't pass the image file, then the API didn't show any error. But I need to pass the image file to get the correct result.
As I Explicitly throw Exception, so its throwing exception like Faild to fetch and message in ScaffoldMessenger --> Somthing went wrong
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var postUri = Uri.parse("http://medbo.digitalicon.in/api/medboapi/SaveCustomTestBooking");
var request = http.MultipartRequest('POST', postUri);
request.fields['VisitDate'] = _selectedDate;
request.fields['EncUserId'] = EncUserId;
request.files.add(new http.MultipartFile.fromBytes('image',await File.fromUri(Uri.parse(image!.path)).readAsBytes(),contentType: new MediaType('image', 'jpeg')));
request.send().then((response) {
if (response.statusCode == 200) {
print("Uploaded!");
Navigator.push(context,MaterialPageRoute(builder: (context) => DieticianAfterDateSelectPage(rresponse:DieticianEncBookingIdModel.fromJson(jsonResponse),)));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Somthing went wrong")));
throw Exception("Faild to fetch");
}
});
}
}
You should use MultiPart post method. Take a look at this.
You can pass image file simply in this way:
//header
var headers = {
'content-type': 'multipart/form-data',
'Accept': 'application/json',
};
//setup request
var request = http.MultipartRequest(
"POST", Uri.parse("your api url"));
//add files to reqest body
request.files.add(await http.MultipartFile.fromPath(
'your feild name',
pickedFile.path,
));
//add header
request.headers.addAll(headers);
//send request and return response
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
}
Finally managed to slove it using Multipart.. Here is full API function code of mine
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var response = http.MultipartRequest('POST',Uri.parse("http://myApiTestBooking"));
response.fields['VisitDate'] = _selectedDate;
response.fields['EncUserId'] = EncUserId;
response.fields['Description'] = testTextController.text;
response.files.add(new http.MultipartFile.fromBytes(
"UserFile", File(image!.path).readAsBytesSync(),//UserFile is my JSON key,use your own and "image" is the pic im getting from my gallary
filename:"Image.jpg",
contentType: MediaType('image', 'jpg')));
response.send().then((response) async {
if (response.statusCode == 200){
isApiCallProcess = false;
final respBody = await response.stream.bytesToString();// this is how we print body for Multipart request
jsonResponse = json.decode(respBody.toString());
print(respBody);
print("Uploaded!");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Booked"),
backgroundColor: Color(0xFF00b3a4),
));
// Navigator.push(context,new MaterialPageRoute( builder: (context) =>new MyTestReqDetailsPage(),));
Navigator.push(context,new MaterialPageRoute( builder: (context) =>new Home2(),));
}
});
}
}

I am trying to store the Authorization Token fetched from the Rest API and then use it in the headers of other API calls in Flutter

As the title of the problem explains most of it but will still elaborate more.
So I am calling an API using the POST method and registering a user which gives me response data containing only the Authorization token which needs to be used while calling other APIs.
Now I want to store the token and use it in the headers while making other API calls.
I am herewith attaching a few code snippets that might demonstrate what I have done actually and what needs to be done in order to get the particular outcome.
I am getting the API response for fetching the key but I am unable to understand why it is not getting stored and why cannot I use it in the headers.
API call that returns just the token in the response
final storage = SecureStorage();
Future<UserRegistration> registration(dynamic param) async {
var client = http.Client();
try {
var response = await client
.post(Uri.https("baseURL", "endpoint"),
body: param)
.timeout(Duration(seconds: TIME_CONST))
.catchError(handleError);
if (response.statusCode == 201) {
print('Response Body: ${response.body}');
final data = jsonDecode(response.body);
///////Using the flutter secure storage here to save the token
var token = storage.writeSecureToken('key', data['key']);
print("Token Here $token");
return UserRegistration(
key: data['key'],
status: true,
);
} else {
print("Something went wrong");
return param;
}
} on SocketException {
throw FetchDataException('message', 'url');
} on TimeoutException {
throw ApiNotRespondingException("message", "url");
}
}
API response that I am getting
Response Body: {"key":"8fb303212871a80899f0b883f3554b189fddf24b"}
API call that I am making which requires the Authorization Header as the key received in the previous response.
Future<PhoneOTPValidate> phoneOTPvalidate(dynamic param) async {
var client = http.Client();
var token = storage.readSecureToken('key');
try {
var response = await client
.post(
Uri.https("baseURL", "endpoint"),
headers: <String, String>{
'Authorization': 'Token $token',
},
body: param)
.timeout(Duration(seconds: TIME_CONST))
.catchError(handleError);
if (response.statusCode == 200) {
print('Response Body: ${response.body}');
final data = jsonDecode(response.body);
return PhoneOTPValidate(
status: data['success'],
validate: true,
);
} else {
print("The OTP is not valid");
return param;
}
} on SocketException {
throw FetchDataException('message', 'url');
} on TimeoutException {
throw ApiNotRespondingException("message", "url");
}
}
My Classes for the above API calls are here:
class PhoneOTPValidate {
PhoneOTPValidate({this.status, this.validate});
final String? status;
final bool? validate;
}
class UserRegistration {
UserRegistration({this.key, this.status});
final String? key;
final bool? status;
}
Flutter Secure Storage Class
class SecureStorage {
final storage = FlutterSecureStorage();
Future writeSecureToken(String key, String value) async {
var writeData = await storage.write(key: key, value: value);
print('Token Here');
return writeData;
}
Future readSecureToken(String key) async {
var readData = await storage.read(key: key);
return readData;
}
Future deleteSecureToken(String key) async {
var deleteData = await storage.delete(key: key);
return deleteData;
}
}
Here's the output for what I have written:
Response Body: {"key":"de18d1239ed0b6be13f4c9a9d96eebeb1c401922"}
I/flutter (23010): Token Here Instance of 'Future<dynamic>'
I/flutter (23010): Token Here
How do I solve this problem of saving the key and using it in the headers of the other API calls?
Have almost tried all the solutions from StackOverflow but nothing gave a solid answer to how it is being done.
Am stuck at this problem for quite a few days
Would appreciate it if anyone can solve my problem considering my code.
The problem is that you don't "await" for secure token to be read and written. This can easily be avoided by providing explicit types for you variables. Let's fix your code:
// I assume you are using null-safety
class SecureStorage {
final FlutterSecureStorage storage = FlutterSecureStorage();
Future<void> writeSecureToken(String key, String value) async {
// I'm not exactly sure how you get the data from storage.write, because it has a type of Future<void>
// So the whole function should be await storage.write(key: key, value: value);
await storage.write(key: key, value: value);
}
Future<String?> readSecureToken(String key) async {
return await storage.read(key: key);
}
Future<void> deleteSecureToken(String key) async {
// Same here: delete is a type of void, so it shouldn't return anything
await storage.delete(key: key);
}
}
Then with updating secured storage finished we can move to getting the token
final storage = SecureStorage();
Future<UserRegistration> registration(dynamic param) async {
var client = http.Client();
try {
var response = await client
.post(Uri.https("baseURL", "endpoint"), body: param)
.timeout(Duration(seconds: TIME_CONST))
.catchError(handleError);
if (response.statusCode == 201) {
print('Response Body: ${response.body}');
final data = jsonDecode(response.body);
///////Using the flutter secure storage here to save the token
String? token = data['key'];
if (token == null) {
throw Exception("No token in response");
}
await storage.writeSecureToken('key', token);
print("Token Here $token");
return UserRegistration(
key: token,
status: true,
);
} else {
print("Something went wrong");
return param;
}
} on SocketException {
throw FetchDataException('message', 'url');
} on TimeoutException {
throw ApiNotRespondingException("message", "url");
}
}
and finally fix the read for the token when you make a call:
Future<PhoneOTPValidate> phoneOTPvalidate(dynamic param) async {
var client = http.Client();
// Added type String? on the left side and await keyword for the storage.read()
String? token = await storage.readSecureToken('key');
if (token == null) {
throw Exception("No token stored in storage");
}
try {
var response = await client
.post(
Uri.https("baseURL", "endpoint"),
headers: <String, String>{
'Authorization': 'Token $token',
},
body: param,
)
.timeout(Duration(seconds: TIME_CONST))
.catchError(handleError);
if (response.statusCode == 200) {
print('Response Body: ${response.body}');
final data = jsonDecode(response.body);
return PhoneOTPValidate(
status: data['success'],
validate: true,
);
} else {
print("The OTP is not valid");
return param;
}
} on SocketException {
throw FetchDataException('message', 'url');
} on TimeoutException {
throw ApiNotRespondingException("message", "url");
}
}

Flutter : got an error when i try to convert an int to json in the body of the post requestFl

When I try to convert a dart code to json for a post request I got this error
'"type 'int' is not a subtype of type 'String' in type cast"',
in the body of the request required [numberOfPerson] to be integer.
This is the method which i use to post a request:
Future<void> createReservation(String fromTime, String toTime, String areaId,
int numberOfPerson, String date) async {
Map<String, dynamic> data = Map<String, dynamic>();
data['area_id'] = areaId;
data['number_of_people'] = numberOfPerson;
data['from_time'] = date + " " + fromTime;
data['to_time'] = date + " " + toTime;
final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey(Constant.prefsUserAccessTokenKey)) {
token = prefs.getString(Constant.prefsUserAccessTokenKey);
}
final url = Urls.create_reservasion;
try {
final response = await retry(
() => http
.post(url,
headers:
'Authorization': 'Oauth2 ' + token
},
body: data)
.timeout(Duration(seconds: 5)),
retryIf: (e) => e is TimeoutException || e is SocketException);
print('create reservation is:');
print(response.body);
if (response.statusCode == 200) {
} else if (response.statusCode == 401) {
throw HttpException('401');
} else if (response.statusCode == 500) {
print('server error');
print(response.statusCode);
throw HttpException("Something went wrong");
} else {
print(json.decode(response.body)['detail']);
print(response.statusCode);
throw HttpException(json.decode(response.body)['detail']);
}
} catch (error) {
throw error;
}
}
And this is the body of the json request:
{
"area_id":"282b1837-c052-4ae7-89e5-171787599362",
"number_of_people":1,
"from_time":"2020-09-22 14:00:00",
"to_time":"2020-09-22 14:30:00"
}

Post form data to server flutter

I have been having a lot of trouble sending a post request to a server. It expects a form data type.
This is the error I get after my input.
`image: [The image must be an image.]}}
Most of my data are strings except for an int and a file Image which is selected from gallery by user.
This is my code:
dart code
if(_image!=null){
setState(() {
_isLoading = true;
});
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
var uri = NetworkUtils.host +
AuthUtils.updateSessionRequest;
Map<String, String> data = {"_method": "PATCH",
"first_name": widget.first_name,
"last_name": widget.last_name,
"phone": widget.phone,
"industry":widget.industry,
"country": widget.country,
"state": widget.state,
"fav_quote": widget.fav_quote,
"bio_interest": widget.bio_text,
"terms": "1",
"company": widget.company,
"position": widget.job_position,
"linked_in":widget.linkedin_profile,
"institution": widget.institution,
"degree": widget.degree,
"preference[0]": widget.industry};
String authToken = sharedPreferences.getString("token");
try {
final response = await http.post(
uri,
body: data,
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer ' + authToken,
},
);
final responseJson = json.decode(response.body);
print(responseJson.toString());
if (response.statusCode == 200 || response.statusCode == 201) {
//upload image to server after success response
uploadImage(_image);
NetworkUtils.showToast("Profile successfully update!");
});
} else{
setState(() {
_isLoading = false;
});
NetworkUtils.showSnackBar(_scaffoldKey, 'An error occurred. Please try again');
}
return responseJson;
} catch (exception) {
print(exception.toString());
setState(() {
_isLoading = false;
});
NetworkUtils.showSnackBar(_scaffoldKey, 'An error occurred. Please try again');
}
}
uploadImage(File image) async{
var request = http.MultipartRequest(
"POST",
Uri.parse(NetworkUtils.host +
AuthUtils.endPointUpdateProfile));
request.files.add(await http.MultipartFile.fromPath(
'image',
image.path,
));
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
}
}
You need to pass your image like this
request.files.add(await http.MultipartFile.fromPath(
'image',
_image,
));
Here an example how to pass File and String using http
var request = http.MultipartRequest(
"POST",
Uri.parse("http://....."));
request.fields['first_name'] = widget.first_name;
request.fields['last_name'] = widget.last_name;
.....
request.files.add(await http.MultipartFile.fromPath(
'image',
path,
));
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
From the above only, with a little modification
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void executePostMethod(String title) async {
var request = http.MultipartRequest("POST", Uri.parse("https://localhost:44377/API/GetStateList"));
request.fields['CountryID'] = "1";
// .....
//request.files.add(await http.MultipartFile.fromPath('image',path,)
//);
// send request to upload image
await request.send().then((response) async {
//print(response);
response.stream.transform(utf8.decoder).listen((value) async {
print(value);
// print("ResponseVal: $value");
if (response.statusCode == 200) {
var imgUploadData = json.decode(value);
print(imgUploadData);
} else {
throw Exception("Faild to Load!");
}
});
}).catchError((e) {
print(e);
});
}