I'm really new in Flutter programming. I've problem while try to get value from Future. After I get it, I want to deserialize it for further processing.
The return value from the Future is on JSON Array.
What should I do to solve this situation?
class _MyAppState extends State<BodyWidget>
{
bool loading = true;
List<Widget> listArray = [];
Dio dio = new Dio();
dynamic isicontent = null;
Future<dynamic> getOrderHistory() async {
final String pathUrl = "http://p.q.r.s/mobile/QIXGetShipmentHistory/" + await FlutterSession().get("MobileUsername");
var responseDio = await dio.get(pathUrl, options: Options( headers: {'Content-Type': 'application/json; charset=UTF-8' } ) );
print(responseDio.data); // It's works fine here...
return responseDio.data;
}
void renderIconShipmentOrderHistory()
{
var resultRespon = getOrderHistory();
print(resultRespon); //the problem is here...
}
}
The return statement needs to return a Future; something alike:
return dio.get(
pathUrl,
options: Options(
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
)
)
The async keyword from the signature likely can be removed, as there is no more await.
Obviously, not returning a Future but awaiting the result may be the other option.
Related
I have an application that caters for web, android and ios.
I have implemented the packages below
https://pub.dev/packages/image_picker/example
image_picker: ^0.8.2
image_picker_for_web: ^2.1.1
Tasks:
User needs to select multiple images (When debugging thru android, i sometimes receive websocket connection expection, and application exits without any error message. Bonus if youre able to provide some insights to this issue as well)
Clicks submit to upload the images (XFile) to API
class UserAttachments {
List<XFile>? attachments = [];
int userID = 0;
}
Future<String> submitImage(UserAttachments ua) async {
http.MultipartRequest request =
new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));
Map<String, String> headers = {"Content-Type": "application/json"};
ua.attachments!.forEach((element) async {
var bytes = element.readAsBytes();
request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
});
request.headers.addAll(headers);
request.fields['userID'] = '23';
http.StreamedResponse responseAttachmentSTR = await request.send();
print(responseAttachmentSTR.statusCode);
return "SENT"; // + " - Respomse: " + map.toString();
}
Above code doesn't seem to work. Any solutions that cater for web/android/ios?
You can't use async on forEach, because that will just return an array of promises and won't wait for them. To fix this, you can use a for loop for asynchronous functions.
for(var i = 0; i < ua.attachments!.length; i++) {
var element = ua.attachments[i];
var bytes = element.readAsBytes();
request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
}
And you can optimize this code using Future.wait
Future<String> submitImage(UserAttachments ua) async {
http.MultipartRequest request =
new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));
Map<String, String> headers = {"Content-Type": "application/json"};
var bytes = await Future.wait(ua.attachments!.map((el) => el.readAsBytes()));
request.files.addAll(bytes.map((b) => new http.MultipartFile.fromBytes('file', b)));
request.headers.addAll(headers);
request.fields['userID'] = '23';
http.StreamedResponse responseAttachmentSTR = await request.send();
print(responseAttachmentSTR.statusCode);
return "SENT";
}
I am trying to upload multiple image in server using android application which is builds with flutter language. Here is the code which I am trying.
static Future postDataWithFile(......List<File> images) async {
Map<String, String> headers = {
"Accept": "application/json",
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
var request = http.MultipartRequest('POST', Uri.parse(url));
request.headers.addAll(headers);
request.fields['contact'] = insertVisitedPlace.contact;
request.fields['ownerName'] = insertVisitedPlace.ownerName;
request.fields['orgName'] = insertVisitedPlace.orgName;
request.fields['orgtype'] = insertVisitedPlace.orgType.toString();
request.fields['nextFollowup'] = insertVisitedPlace.nextFollowup ?? "";
..............................
Here I am use a List to store all image.
List<MultipartFile> allImagesAfterConvert = [];
images.forEach((image) {
allImagesAfterConvert.add(
await http.MultipartFile.fromPath(
'orgImages',
image.path,
)
);
});
Send request to server to add all images. But In the server get only one image.
request.files.addAll(allImagesAfterConvert);
try {
final response = await request
.send()
.timeout(Duration(seconds: timeoutSeconds), onTimeout: () {
throw TimeoutException("Connection time out. Please try again");
});
return _isValidResponse(response) ? response : _error(response);
} on SocketException {
throw Failure("No Internet Connection");
} on TimeoutException {
throw Failure("Request time out");
} on Error catch (e) {
throw Failure(e.toString());
}
}
Replace orgImages with orgImages[]
images.forEach((image) {
allImagesAfterConvert.add(
await http.MultipartFile.fromPath(
'orgImages[]’,
image.path,
)
);
});
This should work.
I'm trying to send a fetch request using post to an api, I'm doing a search using a keyword and it should return a JSON containing users, whenever I try this on Android using expo it doesn't work however it seems to work on iOS using expo. The error I get back is a JSON parse error, I get a status code of 308.
import User from '../../Model/User';
import { BearerToken } from '../../Constants/BearerToken';
export const GETRESULTS = 'GETRESULTS';
export const getResults = (item) => {
return async dispatch => {
const response = await fetch("https://example.com",
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': BearerToken
},
body: JSON.stringify({
query: item
}),
redirect: 'follow'
}
);
console.log(response.status);
if(!response.ok) {
console.log("fack off");
const errorResData = await response.json();
console.log(errorResData);
let message = 'Something went wrong';
throw new Error(message);
}
const resData = await response.json();
const searchResultsArray = [];
for(const searchResult in resData){
searchResultsArray.push(new User(
resData[searchResult].education,
resData[searchResult].email,
resData[searchResult].full_name,
resData[searchResult].gender,
resData[searchResult].job_title,
resData[searchResult].location,
resData[searchResult].password,
resData[searchResult].phone,
resData[searchResult].preferred_name,
resData[searchResult].profile_image,
resData[searchResult].profile_type,
resData[searchResult].score,
resData[searchResult].short_bio,
resData[searchResult].story
)
);
}
dispatch({type: GETRESULTS,usersArray:searchResultsArray});
};
};
What worked for me was putting 'https://example.com/search/' basically at a slash at the end fixed it for me
while trying to get the list of countries from my api, my code is sendig unlimited request to the server when i call the function one time. here is the flutter code
Future<dynamic> listePays() async{
http.Response response = await http.get(apiUrl+"api_pays", headers: {"Accept": "application/json"});
var resp = json.decode(response.body);
return resp;
}
i want to send just one request and work with the answers. ihave tried removing Future but i get the same issue
i call the function like this:
getPays() async {
Functions().listePays().then((data) async {
pays = data;
setState(() {});
});
}
I am using asp.net core web API as back-end. There is a method that accepts a single integer value.
Method([FromBody] int value)
I want to post the integer value from dart/flutter.
I tried the following with the dart http package.
Http.post(url, body:0,headers:{"content-type":"application/json"}
Http.post(url, body:{0},headers:{"content-type":"application/json"}
Http.post(url, body:convert.jsonEncode(0),headers:{"content-type":"application/json"}
Http.post(url, body:convert.jsonEncode({0}),headers:{"content-type":"application/json"}
All my above tries failed with error
"Invalid argument: invalid request body "0""
I had the same problem when trying to send an HTTP request to an API that has an integer as one of its arguments(age). Dart wanted me to convert the int into a string and the API was not accepting the int as a string. Hence I was getting the same error and ended up in this question.
My solution was to store the input in a map, add a header {"content-type":"application/json"} and pass the map in the body arguement.
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<String> register_user() async {
var req_body = new Map();
req_body['username'] = 'John Doe';
req_body['age'] = 20; /* The integer */
final response = await http.post(
'http://127.0.0.1:8081/user/register',
headers: {'Content-Type': 'application/json'},
body: jsonEncode(req_body));
if (response.statusCode == 200) {
var object = json.decode(response.body);
return object.toString();
} else if (response.statusCode == 422) {
return 'Error';
} else {
return 'Can not connect to server';
}
}
Please refer my code
import
import 'package:http/http.dart' as http;
http request
var client = new http.Client();
client.post(Uri.encodeFull("Your url"), body: {
"param1": "value1",
"param2": 11, // integer value type
}).then((response) {
client.close();
if (this.mounted && response.statusCode == 200) {
//enter your code for change state
}
}).catchError((onError) {
client.close();
print("Error: $onError");
});
I hope it will help you.
PS:
var client = new http.Client();
var response = await client.post(Uri.encodeFull("Your Url"), body : "0", header : {/*Your headers*/"});
You can try this code.
Http.post(url, body:{"id": "0"},headers:{"content-type":"application/json"}
Can you try bellow one
var queryParameters = {
'value': '0'
};
var uri =
Uri.https('www.myurl.com', '/api/sub_api_part/', queryParameters); //replace between part and your url
var response = await http.get(uri, headers: {
HttpHeaders.contentTypeHeader: 'application/json'
});