TimeStamps for DateTime and Time siche Epoch Dart? - flutter

How to create timestamps in dart? I have found many solution but non of them works. I need to put in get-request the timestamps. Server takes timestamps in time siche epoch format. I was trying this:
_asyncMethod() async {
var url =
"https://link/cameras/snapshot/$formatDate"; // <-- 1
var response = await http.get(Uri.parse(url), headers: {
'cookie': cookies,
'login': userName,
'password': password,
'key': apiKey
});
print(response.body);
var documentDirectory = await getApplicationDocumentsDirectory();
var firstPath = documentDirectory.path + "/image";
var filePathAndName = documentDirectory.path + 'image/png';
await Directory(firstPath).create(recursive: true);
File file2 = File(filePathAndName);
file2.writeAsBytesSync(response.bodyBytes);
setState(() {
imageData = filePathAndName;
dataLoaded = true;
});
}
String imageData;
bool dataLoaded = false;
String formatDate(int milliseconds) {
final template = DateFormat('yyyy-MM-dd');
return template.format(DateTime.fromMillisecondsSinceEpoch(milliseconds));
}
but the answer from the server is
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|3fc1bda-4c3086a677e6762a.","er
rors":{"timestamp":["The value 'Closure: (int) => String from Function 'formatDate':.' is not valid."]}}
I understand that the data is not correct but I can't understand how to solve it, because it seems like code for timestamps is correct

Related

Flutter await does not await until return of function

I tried to find an answer but my problem is still there.
In my asynchronous upload function I return at the and the generated name of the image, which I want to use to make my database request.
This is my upload function:
Future<String> upload(File imageFile) async {
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length();
var uri = Uri.parse("http://localhost:8080/upload");
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
var createdFileName = "";
response.stream.transform(utf8.decoder).listen((value) {
createdFileName = value;
print(createdFileName);
});
return createdFileName;
}
I call it like this:
List createdFileNames = [];
for (var e in imagefiles) {
createdFileNames.add(await upload(File(e)));
}
I don't know why, but the createdFileNames are ["",""], but the upload gives as result the right name. In debug mode I can see, that the loop does not wait until the upload has finished.
Do you have any suggestions?
Thank you very much!
response.stream.transform(utf8.decoder).listen((value) {
createdFileName = value;
print(createdFileName);
});
This part in your function is asynchronous, it uses a callback.
But you don't wait for it to finish in any form. You just continue to return the createdFileName, that by that time most likely has not been filled.
I don't know what your stream looks like, if you only need the first value, you could await that instead of listening:
createdFileName = await response.stream.transform(utf8.decoder).first;
Replace
response.stream.transform(utf8.decoder).listen((value) {
createdFileName = value;
print(createdFileName);
});
with
createdFileName=await response.stream.bytesToString();
change code
for (var e in imagefiles) {
upload(File(e)).then((value) => createdFileNames.add(value));
}

how to parse the answer (array) you get in the API (GET) query in flutter

I'm querying get into flutter, and I'm getting back array (one object in the array). I want to parse this answer and assign the data from the array object to the variable. But I can't do it. Here is my request:
Future<Null> example(
String? task_id
) async {
HttpClient client = new HttpClient();
client.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
final String url = urlVar "?id="+ '$task_id';
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
Map jsonResponse = json.decode(responseBody);
print(jsonResponse);
}
My answer json
[
{
"id": "d290111e-6c54-4b01-90e6-d701748f0851",
"name": "Parse example",
}
]
I want to parse this answer and assign it to my variables. I did it like when the answer was in the object, I did it like this. But with array not, I will be grateful for help)
var responseBody = await response.transform(utf8.decoder).join();
Map jsonResponse = json.decode(responseBody);
print(jsonResponse);
if (response.statusCode == 200) {
global.taskId = jsonResponse['id'] ;
global.taskName = jsonResponse['name'];
}
Try this
if (response.statusCode == 200) {
global.taskId = jsonResponse[0]['id'] ;
global.taskName = jsonResponse[0]['name'];
}

Flutter/Dio Hangs when in an isolate

So I'm trying to sync my database in an isolate, since UI doesn't care about the sync.
Database _backgroundConnection(File dbFile) {
final database = VmDatabase(dbFile);
var connection = DatabaseConnection.fromExecutor(database);
return Database.connect(connection);
}
Dio _getDio(String urlBase, String authToken) {
var dio = Dio();
dio.options.baseUrl = urlBase;
dio.options.headers = {"Authorization": authToken};
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout = 3000;
return dio;
}
Future<void> _syncUser(UserDao dao, DateTime lastSynced, Dio dio) async {
var users = await dao.getUser();
if (users.isEmpty) {
return;
}
var user = users[0];
var userDto = UserDto.fromUser(user);
//if (user.lastUpdated.isAfter(lastSynced)) {
var result = await dio.put("/api/v1/user", data: userDto.toJson());
print(result);
//}
}
Future<void> _startSync(Map<String, dynamic> info) async {
String dbPath = info["dbPath"];
DateTime lastSynced = info["lastSynced"];
String urlBase = info["url"];
String token = info["token"];
var dio = _getDio(urlBase, token);
File dbFile = File(dbPath);
var database = _backgroundConnection(dbFile);
_syncUser(UserDao.fromDatabase(database), lastSynced, dio);
}
class DatabaseSync {
Future<void> syncDatabase() async {
final dbFolder = await getApplicationDocumentsDirectory();
var envVars = GetIt.instance.get<EnvVariables>();
var authRepo = GetIt.instance.get<FirebaseAuthRepository>();
compute(_startSync, {
"lastSynced": DateTime.now(),
"dbPath": p.join(dbFolder.path, 'db.sqlite'),
"url": envVars.url,
"token": await authRepo.getAuthToken(),
});
}
}
I've removed the compute portion, and just ran the code, and it works. It makes the request. However when I put a breakpoint at just before the request, it hits, but when I put it on the print statement, it never hits. Nothing is ever written to the console. This happens on both iOS and android. I tried changing the urlBase from my localhost server to https://google.com to make sure it would hit something https (since iOS gets picky) and still nothing.
So this is kinda strange but calling await _syncUser(...) fixed the problem.

Flutter/Dart - Why does my Future return Null?

I want to return a string extracted from the response.body of an Http Post. But my code returns null instead of the string. The string oldname will print just fine if I put it in the scope of request.send() but I need it to be returned when calling the uploadAudio method. What am I doing wrong?
Future<String> uploadAudio({String currentuserid, String filepath}) async {
String oldname;
final serverurl = "http://example.com/audiofile.php";
var request = http.MultipartRequest('POST', Uri.parse(serverurl));
request.fields['userid'] = currentuserid;
var multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
contentType: MediaType("audio", "mp4"));
request.files.add(multiPartFile);
request.send().then((result) async {
http.Response.fromStream(result).then((response) {
if (response.statusCode == 200) {
String serverResponse = response.body;
const start = "gxz";
const end = "zxg";
final startIndex = serverResponse.indexOf(start);
final endIndex = serverResponse.indexOf(end, startIndex + start.length);
oldname = serverResponse.substring(startIndex + start.length, endIndex);
}
});
});
print oldname;
return oldname;
}
I think your confusion comes from the fact you are mixing the use of await and then(). I will recommend you are staying with one concept in general.
I have rewritten your code so it is now using await everywhere (also cleaned it a little bit up):
Future<String> uploadAudio({String currentuserid, String filepath}) async {
const serverurl = "http://example.com/audiofile.php";
final request = http.MultipartRequest('POST', Uri.parse(serverurl))
..fields['userid'] = currentuserid;
final multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
contentType: MediaType("audio", "mp4"));
request.files.add(multiPartFile);
final response = await http.Response.fromStream(await request.send());
String oldname;
if (response.statusCode == 200) {
final serverResponse = response.body;
const start = "gxz";
const end = "zxg";
final startIndex = serverResponse.indexOf(start);
final endIndex = serverResponse.indexOf(end, startIndex + start.length);
oldname = serverResponse.substring(startIndex + start.length, endIndex);
}
print(oldname);
return oldname;
}
As you can see, the code are much easier to read now without all that nested then() methods.
Await your futures:
Future<String> uploadAudio({String currentuserid, String filepath}) async {
String oldname;
final serverurl = "http://example.com/audiofile.php";
var request = http.MultipartRequest('POST', Uri.parse(serverurl));
request.fields['userid'] = currentuserid;
var multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
contentType: MediaType("audio", "mp4"));
request.files.add(multiPartFile);
await request.send().then((result) async {
await http.Response.fromStream(result).then((response) {
if (response.statusCode == 200) {
String serverResponse = response.body;
const start = "gxz";
const end = "zxg";
final startIndex = serverResponse.indexOf(start);
final endIndex = serverResponse.indexOf(end, startIndex + start.length);
oldname = serverResponse.substring(startIndex + start.length, endIndex);
}
});
});
print(oldname);
return oldname;
}

how to upload image to rest API in flutter through http post method?

I'm trying to upload an image through the flutter via post method. and I'm using image_picker for pick file from mobile but I can't able to upload
and I have tried to send the file like FormData that also doesn't work
Future<dynamic> uploadLicence(int id ,dynamic obj) async {
FormData formdata = new FormData(); // just like JS
formdata.add("image",obj);
final response = await post('Logistic/driver/LicenceImage?
driverId=$id',
formdata);
print(response);
// return null;
if (response.statusCode == 200) {
final result = json.decode(response.body);
return result;
} else {
return null;
}
}
after that, I just tried with this method but this also not working
Future<dynamic> uploadLicence(int id, File file) async {
final url = Uri.parse('$BASE_URL/Logistic/driver/LicenceImage?
driverId=$id');
final fileName = path.basename(file.path);
final bytes = await compute(compress, file.readAsBytesSync());
var request = http.MultipartRequest('POST', url)
..files.add(new http.MultipartFile.fromBytes(
'image',bytes,filename: fileName,);
var response = await request.send();
var decoded = await
response.stream.bytesToString().then(json.decode);
if (response.statusCode == HttpStatus.OK) {
print("image uploded $decoded");
} else {
print("image uplod failed ");
}
}
List<int> compress(List<int> bytes) {
var image = img.decodeImage(bytes);
var resize = img.copyResize(image);
return img.encodePng(resize, level: 1);
}
It's possible with MultipartRequest. Or you can use simply dio package. It's one command.
With http:
import 'package:http/http.dart' as http;
final Uri uri = Uri.parse(url);
final http.MultipartRequest request = http.MultipartRequest("POST", uri);
// Additional key-values here
request.fields['sample'] = variable;
// Adding the file, field is the key for file and file is the value
request.files.add(http.MultipartFile.fromBytes(
field, await file.readAsBytes(), filename: filename);
// progress track of uploading process
final http.StreamedResponse response = await request.send();
print('statusCode => ${response.statusCode}');
// checking response data
Map<String, dynamic> data;
await for (String s in response.stream.transform(utf8.decoder)) {
data = jsonDecode(s);
print('data: $data');
}
I user this code for my project i hope work for you
Upload(File imageFile) async {
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var uri = Uri.parse(uploadURL);
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
//contentType: new MediaType('image', 'png'));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}