i trying to create post function in flutter
here is my code:
Future<String> makePostRequest() async {
String requestResult;
var body = this.toMapRequest();
String requestUrl = RequestZarinpal.PAYMENT_REQUEST_URL;
String gateWayUrl;
String jsonBody = json.encode(body);
final encoding = Encoding.getByName('utf-8');
Response response = await post(
requestUrl,
headers: headers,
body: jsonBody,
encoding: encoding,
).timeout(const Duration(seconds: 10), onTimeout: () {
throw TimeoutException('The connection has timed out, Please try again!');
});
responseBody = response.body;
var parsedJson = json.decode(responseBody);
var data = parsedJson['data'];
var error = parsedJson['errors'];
if (error.toString() != "[]") {
var errorcode = parsedJson['errors']['code'];
print("$body va $requestUrl va $parsedJson");
requestResult = " شما ارور زیر را دریافت کرده اید \n$error";
} else if (data.toString() != "[]") {
var authority = parsedJson['data']['authority'];
requestResult = "اتوریتی شما با موفقیت ساخته شد و به درگاه متصل می شود";
_request.setAuthority(authority);
print(parsedJson);
String gateWay = RequestZarinpal.PAYMENT_GATEWAY_URL;
gateWayUrl = "$gateWay$authority";
if (await canLaunch(gateWayUrl)) {
await launch(
gateWayUrl,
forceSafariVC: false,
forceWebView: false,
headers: headers,
);
} else {
throw 'Could not launch $requestUrl';
}
print(requestResult);
return requestResult;
}
}
but i got this error:
The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.dart(body_might_complete_normally)
what should i do?
With the line if (error.toString() != "[]") you divided your function in 2 possibile outcome.
The positive one, doesn't have a return.
Maybe you should move return requestResult; after the curly bracket, so that the return gets fired regardless.
You are missing the return statement inside the if condition
if (error.toString() != "[]") {
var errorcode = parsedJson['errors']['code'];
print("$body va $requestUrl va $parsedJson");
requestResult = " شما ارور زیر را دریافت کرده اید \n$error";
return requestResult;
}
Related
i'm making an FTP connection with sockets.
Everything works without TLS but when i start PASV in TLS mode, i can connect to data socket but i can't listen nothing.
Could someone help me to understand where i'm wrong?
This is the code i'm using:
String? pasvIP;
int? pasvPort;
RawSocket rawsock = await RawSocket.connect(ftpHost!, int.parse(port));
StreamSubscription<RawSocketEvent> rwlisten = rawsock.listen((event) {
if (event == RawSocketEvent.read) {
Uint8List? buffer = rawsock.read();
String result = String.fromCharCodes(buffer!);
print(' ${result}');
}
});
rawsock.write(Utf8Codec().encode('AUTH TLS\r\n'));
rawsock = await RawSecureSocket.secure(
rawsock,
onBadCertificate: (certificate) => true,
subscription: rwlisten,
);
rwlisten = rawsock.listen((event) {
if (event == RawSocketEvent.read) {
Uint8List? buffer = rawsock.read();
String result = String.fromCharCodes(buffer!);
print('${result}');
if (result.startsWith('227')) {
final startIndex = result.indexOf('(');
final endIndex = result.indexOf(')');
String ipPasv = result.substring(startIndex + 1, endIndex);
List ipPasvList = ipPasv.split(',');
pasvIP =
'${ipPasvList[0]}.${ipPasvList[1]}.${ipPasvList[2]}.${ipPasvList[3]}';
pasvPort =
(int.parse(ipPasvList[4]) * 256 + int.parse(ipPasvList[5]));
}
}
});
rawsock.write(Utf8Codec().encode('PBSZ 0\r\n'));
rawsock.write(Utf8Codec().encode('PROT P\r\n'));
rawsock.write(Utf8Codec().encode('USER ${username}\r\n'));
rawsock.write(
Utf8Codec().encode('PASS ${activeUser!.decrypt(password!)}\r\n'));
rawsock.write(Utf8Codec().encode('PASV\r\n'));
SecureSocket sockData = await SecureSocket.connect(
pasvIP!,
pasvPort!,
onBadCertificate: (certificate) => true,
);
sockData.listen(
(data) { // <-- NO DATA HERE
final serverResponse = String.fromCharCodes(data);
print('$serverResponse');
},
onError: (error) {
print(error);
sockData.destroy();
},
onDone: () {
print('Server left.');
sockData.destroy();
},
);
rawsock.write(Utf8Codec().encode('LIST\r\n'));
rawsock.write(Utf8Codec().encode('QUIT\r\n'));
Thanks
Marco
How can I get multiple messages from dart isolate?
I'm trying to create an excel file and want to do some operation on that file in an isolate. Before doing an operation on that file, I want to return an message to main isolate, that excel file is created.
Here is function goes in isolate :
foo(String filePath){
// create excel file
var bytes = File(filePath).readAsBytesSync();
var excel = Excel.decodeBytes(bytes);
//HERE I WANT TO SEND THE MESSAGE THAT CREATING EXCEL FILE IS DONE
// some operatoin on excel file
var result = doSomeOperation(excel);
return result;
}
Main isolate code :
var result = await compute(foo, filePath);
What should I do to get creating file message before the actual result comes?
For excel, I'm using excel: ^2.0.0-null-safety-3 package.
Compute only returns one result. If you want to pass multiple 'events' back to the main isolate then you need to use the full Isolate logic (with sendPort and receivePort).
For example, the following code runs in an isolate, and downloads a file while emitting float values to represent progress, potentially a String to indicate log messages and then a bool to indicate success or failure upon completion.
Future<void> isolateDownload(
DownloadRequest request) async {
final sendPort = request.sendPort;
if (sendPort != null) {
var success = false;
var errorMessage = '';
var url = Uri.parse('a_url_based_on_request');
IOSink? out;
try {
http.StreamedResponse response =
await http.Client().send(http.Request('GET', url));
if (response.statusCode == 200) {
var filePath =
join(request.destinationDirPath, '${request.fileName}.ZIP');
var contentLength = response.contentLength;
var bytesLoadedUpdateInterval = (contentLength ?? 0) / 50;
var bytesLoaded = 0;
var bytesLoadedAtLastUpdate = 0;
out = File(filePath).openWrite();
await response.stream.forEach((chunk) {
out?.add(chunk);
bytesLoaded += chunk.length;
// update if enough bytes have passed since last update
if (contentLength != null &&
bytesLoaded - bytesLoadedAtLastUpdate >
bytesLoadedUpdateInterval) {
sendPort.send(bytesLoaded / contentLength);
bytesLoadedAtLastUpdate = bytesLoaded;
}
});
success = true;
if (contentLength != null) {
sendPort.send(1.0); // send 100% downloaded message
}
} else {
errorMessage =
'Download of ${request.fileName} '
'received response ${response.statusCode} - ${response.reasonPhrase}';
}
} catch (e) {
errorMessage = 'Download of ${request.chartType}:${request.chartName} '
'received error $e';
} finally {
await out?.flush();
await out?.close();
if (errorMessage.isNotEmpty) {
sendPort.send(errorMessage);
}
sendPort.send(success);
}
}
}
The code that spawns the isolate then simply checks for the type of the message passed to it to determine the action.
Future<bool> _downloadInBackground(
DownloadRequest request) async {
var receivePort = ReceivePort();
request.sendPort = receivePort.sendPort;
var isDone = Completer();
var success = false;
receivePort.listen((message) {
if (message is double) {
showUpdate(message);
}
if (message is String) {
log.fine(message); // log error messages
}
if (message is bool) {
success = message; // end with success or failure
receivePort.close();
}
}, onDone: () => isDone.complete()); // wraps up
await Isolate.spawn(isolateDownload, request);
await isDone.future;
return success;
}
I have the following method which is use dto verify a ticket/token
var ticketArray = ticket.split('|');
//First check to verify token using simple versification algo
if (widget.eventID.toString() != (ticketArray[0])) {
setState(() {
ticketMainMsg = 'This QR code is NOT VALID';
ticketsubtitle = ticketArray.length != 2
? 'The QR code is fake'
: 'QR code could belong to another event';
ticketStatus = false;
return;
});
}
//Make API call
ticketModel = HttpVerifyTicketPost(
eventId: widget.eventID,
ticket: ticket,
scannerId: widget.scannerId,
).verifyTicket();
}
From above, you can see I do a very simple check on the qr code/token if this simple step fails, I don't bother making an API call and I set the state based on these values.
However if the check passes, then I proceed to make an API call to the server to fully verify the token/code.
My issue is I am struggling to now assign the values from the API call to the ticketStatus, ticketMainMsgand ticketsubtitle parameters. Can anyone helo shed some light. I am quite new to flutter but I am aware that the TicketModel will be a type of Future. My background is PHP so forgive me!
EDIT: The httpVerifyTicket Class
class HttpVerifyTicketPost {
String ticket;
int someId;
int anotherId;
HttpVerifyTicketPost(
{required this.ticket, required this.someId, required this.anotherId});
String verifyURL =
'https://api.com/api/vendors/scanner/native/verify/ticket';
Future<TicketModel> verifyTicket() async {
var storage = await SharedPreferences.getInstance();
var code= storage.getString('code');
var client = http.Client();
var ticketModel = null;
var body = {
'ticket': ticket,
'scanner': scannerCode,
'someId': someId,
'anotherId': anotherId
};
try {
var url = Uri.parse(verifyURL);
var res = await client.post(url, body: jsonEncode(body));
if (res.statusCode == 200) {
var jsonString = res.body;
var jsonMap = json.decode(jsonString);
ticketModel = TicketModel.fromJson(jsonMap);
}
return ticketModel;
} catch (Exception) {
return ticketModel;
}
}
}
Try this please
HttpVerifyTicketPost(
eventId: widget.eventID,
ticket: ticket,
scannerId: widget.scannerId,
).verifyTicket().then((value){setState(() {
ticketModel=value
});
});
I don't quite understand what you want to achieve, but maybe you need to add an asynchronous method like
ticketModel = await HttpVerifyTicketPost( //add await eventId: widget.eventID, ticket: ticket, scannerId: widget.scannerId, ).verifyTicket();
and you must add async like Future Foo() async {your code...}
I need to put some data thorugh api here is my code
static voteplusQuestion(data, int flag){
print('Api');
print(data);
if( flag == 1 ){
var updateQuestionData = {'Would': data.would, 'Rather': data.rather, 'wouldClick': data.wouldClick, 'ratherClick': data.ratherClick + 1, 'QuestionID': data.QuestionID,};
print(updateQuestionData);
}
if( flag == 0){
var updateQuestionData = {'Would': data.would, 'Rather': data.rather, 'wouldClick': data.wouldClick + 1, 'ratherClick': data.ratherClick, 'QuestionID': data.QuestionID,};
print(updateQuestionData);
}
return http.put(
'https://iv9803zj9d.execute-api.us-east-2.amazonaws.com/Development/would-you-rather',
headers: <String, String>{
'Content-Type': 'application/json',
},
);
}
I need to put updateQuestionData to API but i am not sure how can i do this. Also the print output of updateQuestionData is like this
{Would: Shaving Cream, Rather: Soap, wouldClick: 15, ratherClick: 13, QuestionID: 16563fa7-e833-445f-a76b-a9fbaab3a301}
And the Api is working in code pen like this
var xhr = new XMLHttpRequest();
xhr.open('PUT', 'https://iv9803zj9d.execute-api.us-east-2.amazonaws.com/Development/would-you-rather');
xhr.onreadystatechange = function(event) {
console.log(event);
}
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'allow');
xhr.send(JSON.stringify({Would: "Coffe",Rather: "Tea", wouldClick: 15, ratherClick: 13, QuestionID: "16563fa7-e833-445f-a76b-a9fbaab3a301"}));
I have set the header in function but now dont know how can i set the body
You can send data in a put method as follow:
static voteplusQuestion(data, int flag) async{
var updateQuestionData;
if( flag == 1 ){
updateQuestionData = {'Would': data.would, 'Rather':
data.rather, 'wouldClick': data.wouldClick, 'ratherClick':
data.ratherClick + 1, 'QuestionID': data.QuestionID,};
}
if( flag == 0){
updateQuestionData = {'Would': data.would, 'Rather': data.rather,
'wouldClick': data.wouldClick + 1, 'ratherClick':
data.ratherClick, 'QuestionID': data.QuestionID,};
}
String url = 'https://iv9803zj9d.execute-api.us-east-2.amazonaws.com/Development/would-you-rather';
Map<String, String> headers = {"Content-type": "application/json"};
String data = jsonEncode(updateQuestionData);
// make PUT request
Response response = await put(url, headers: headers, body: data);
// check the status code for the result
int statusCode = response.statusCode;
print(statusCode);
// this API passes back the updated item with the id added
String body = response.body;
print(body);
return body;
}
I am not sure about your use case, but I believe this could be implemented much cleaner.
Note: to use put method or to perform the update operation you need to add the id of the item, I am sure about the url existed in this example
i am not familiar using For-in using dart, i use similar code in ts or angular and it work as expected, but get lost when use flutter and need more guidance to use it.
Future<int> datetransaction(String mid) async {
var url = 'http://callsomehttp.com/$mid';
var res = await http.get(url);
if (res.statusCode == 200) {
var dtpoint = json.decode(res.body);
var availabledate = [];
for (var key in dtpoint) {
var dateEle = dtpoint[key]['Balance']['date'];
if (availabledate.indexOf(dateEle) == -1) {
availabledate.add(dateEle);
totalSpending(dateEle, mid);
}
}
print('available data $availabledate');
var spen = totalTransaction.reduce((a, b) => a + b);
return spen ;
} else {
throw Exception(
"Request to $url failed with status ${res.statusCode}: ${res.body}");
}
}
Future totalSpending (String date, String ckey) async {
var total = 0 ;
final String url = 'http://otherurl.com/$date';
final res = await http.get(url);
if (res.statusCode == 200) {
var pdata = json.decode(res.body);
for (var key in pdata) {
var el = pdata[key]['Transaction']['customer_code'];
var ttl = int.parse(pdata[key]['Transaction']['total']);
if( el == ckey) {
totalTransaction.add(ttl);
total = ttl ;
}
}
return total ;
} else {
throw Exception(
"Request to $url failed with status ${res.statusCode}: ${res.body}");
}
}
any guidance to give a light , or other way to get the result really appreciate, thank you