Flutter http.get - flutter

My problem is, that when I try to map the brands I need to declare brandsData as a Map<String, dynamic> but in that case jsonDecode(s) is red because it could be null

You can change your Model to this .
// To parse this JSON data, do
//
// final album = albumFromJson(jsonString);
import 'dart:convert';
List<Album> albumFromJson(String str) => List<Album>.from(json.decode(str).map((x) => Album.fromJson(x)));
String albumToJson(List<Album> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Album {
Album({
this.userId,
this.id,
this.title,
});
int userId;
int id;
String title;
factory Album.fromJson(Map<String, dynamic> json) => Album(
userId: json["userId"],
id: json["id"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"userId": userId,
"id": id,
"title": title,
};
}
and use the function that #Ravindra via link like this
Future<List<Album>> fetchPost() async {
String url =
'https://jsonplaceholder.typicode.com/albums/1';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Album.fromJson(json
.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Hope it helps you. Lastly you can use this link https://app.quicktype.io/ to create your model class.

Related

How to extract data from a multipart/form-data response?

I am uploading images to a storageAPI using POST method with content-type of multipart/form-data. The api returns an object response that looks as below:
{
"id": "6d50c066-cf65-4748-8b9a-183c3526f49b",
"name": "hotel_6.jpg",
"fileKey": "lv/im/5d9feb8e-2ea8-439d-a550-1e937081e085-hotel_6.jpg",
"fileExtension": ".jpg",
"mimeType": "image/jpeg",
"catalogueUrl": {
"mainUrl": "https://xy.abc.com/lv/im/5d9feb8e-2ea8-439d-a550-1e937081e085-hotel_6.jpg",
"thumbnailUrls": []
},
"createdAt": "2021-11-25T06:40:40.0869466+00:00"
}
How can I extract the variable "mainUrl" from the response so that I can assign its value to the _pictureController? Here is what I have done:
uploadFile() async {
var accessToken = await sharedPref.read(key);
var postUrl = '$baseUrl/catalogue?thumbnail=${param.thumbnailTrueFalse}';
Map < String, String > headers = {
"Authorization": "Bearer $accessToken",
};
// multipart request object
var request = http.MultipartRequest("POST", Uri.parse(postUrl));
request.headers.addAll(headers);
// add selected file with request
request.files.add(http.MultipartFile("file", imageStream, imageSize,
filename: imageName));
// Send request
var response = await request.send();
// Read response
var result = await response.stream.bytesToString();
print('readResponse: $result');
if (response.statusCode == 200) {
var data = StorageResponse.fromJson(jsonDecode(result));
print('data: $data');
setState(() {
_pictureController.text = data.catalogueUrl!.mainUrl!;
});
return data;
} else {
throw Exception('Failed to upload photo.');
}
}
The "StorageResponse" Class is as follows:
#JsonSerializable()
class StorageResponse {
var id;
var name;
var fileKey;
var fileExtension;
var mimeType;
Catalogue ? catalogueUrl;
var createdAt;
StorageResponse({
this.id,
this.name,
this.fileKey,
this.fileExtension,
this.mimeType,
this.catalogueUrl,
this.createdAt,
});
factory StorageResponse.fromJson(Map < String, dynamic > json) =>
_$StorageResponseFromJson(json);
Map < String, dynamic > toJson() => _$StorageResponseToJson(this);
#override
toString() {
String output =
'{id:${this.id},name:${this.name},fileKey: ${this.fileKey},fileExtension:${this.fileExtension},mimeType: ${this.mimeType}mimeType},catalogueUrl: ${this.catalogueUrl},,createdAt: ${this.createdAt}}';
return output;
}
}
You can use the following structure to convert a Json file to a class, and vice versa.
The following structure works properly.
import 'dart:convert';
class StorageResponse {
final String id;
final String name;
final String fileKey;
final String fileExtension;
final String mimeType;
Catalogue catalogueUrl;
final DateTime createdAt;
StorageResponse(
this.id,
this.name,
this.fileKey,
this.fileExtension,
this.mimeType,
this.catalogueUrl,
this.createdAt,
);
factory StorageResponse.fromMap(Map<String, dynamic> json) {
return StorageResponse(
json['id'],
json['name'],
json['fileKey'],
json['fileExtension'],
json['mimeType'],
Catalogue.fromMap(json['Catalogue']),
DateTime.parse(json['createdAt']));
}
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'fileKey': fileKey,
'fileExtension': fileExtension,
'mimeType': mimeType,
'Catalogue': catalogueUrl.toJson(),
'createdAt': createdAt
};
#override
toString() {
String output =
'{id:${this.id},name:${this.name},fileKey: ${this.fileKey},fileExtension:${this.fileExtension},mimeType: ${this.mimeType}mimeType},catalogueUrl: ${this.catalogueUrl},,createdAt: ${this.createdAt}}';
return output;
}
}
class Catalogue {
final String mainUrl;
final List<String> thumbnailUrls;
Catalogue(this.mainUrl, this.thumbnailUrls);
factory Catalogue.fromMap(Map<String, dynamic> json) {
return Catalogue(json['mainUrl'], jsonDecode(json['thumbnailUrls']));
}
Map<String, dynamic> toJson() =>
{'mainUrl': mainUrl, 'thumbnailUrls': jsonEncode(thumbnailUrls)};
}
for use
if (response.statusCode == 200) {
var data = StorageResponse.fromMap(jsonDecode(result));
print('data: $data');
setState(() {
_pictureController.text = data.catalogueUrl!.mainUrl!;
});
return data;
} else {
throw Exception('Failed to upload photo.');
}

Model a server response with Class

I have a flutter application, which uses some server APIs.
When there is a successful response from the server, it would return json back:
{"success": true, "message": "success", "data": {"id": "21EE"} }
However, when there is failure, it would return:
{"success": false, "message": "failure"}
For more strict-typed use of flutter, I try to model the response.
Here is my try:
class ServerResponse {
final bool success;
final String message;
ServerResponse({
required this.success,
required this.message,
});
}
class _AuthAutenticationData {
final String id;
_AuthAutenticationData({
required this.id,
});
}
class AutoAuthenticateResponse extends ServerResponse {
final _AuthAutenticationData? data;
AutoAuthenticateResponse({
required success,
required message,
this.data,
}) : super(success: success, message: message);
}
Now, I have a function which calls a specific API:
Future<void> autoAuth() async {
final url = Uri.parse('${this._baseURL.toString()}/auto-auth');
try {
final response = await http.post(url, headers: {
'Authorization': 'SXXX',
});
print(response.body);
final AutoAuthenticateResponse responseBody = json.decode(response.body);
if (responseBody.success) {
return setUser(new User(id: responseBody.data!.id));
}
setUser(null);
} catch (error) {
print(error);
setUser(null);
}
}
Some code is irrelevant, but bottom line is that I receive the following error in the line: final AutoAuthenticateResponse responseBody = json.decode(response.body);:
I/flutter (14139): type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'AutoAuthenticateResponse'
I guess my solution is bad. Any advice how to fix it?
Well, you can use nullsafety feature for this. Since it's only if when the failure the data is not being returned.
{"success": true, "message": "success", "data": {"id": "21EE"} }
you can use this :
https://meruya-techhnology.github.io/json-to-dart/
Then the result will be a 2 class
class YourClass {
final bool success;
final String message;
final Data? data;
YourClass({this.success, this.message, this.data});
factory YourClass.fromJson(Map<String, dynamic> json) => YourClass(
success : json['success'],
message : json['message'],
data : json['data'] != null ? new Data.fromJson(json['data']) : null;
);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['success'] = this.success;
data['message'] = this.message;
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
And
class Data {
String id;
Data({this.id});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
return data;
}
}
Then you can use it like this :
Future<void> autoAuth() async {
final url = Uri.parse('${this._baseURL.toString()}/auto-auth');
try {
final response = await http.post(url, headers: {
'Authorization': 'SXXX',
});
debugPrint(response.body);
final responseBody = YourClass.fromJson(response.body)
if (responseBody.success) {
return setUser(new User(id: responseBody.data!.id));
}
setUser(null);
} catch (error) {
print(error);
setUser(null);
}
}
another advice is use debugPrint instead of print, here you can read more : https://medium.com/flutter-community/debugprint-and-the-power-of-hiding-and-customizing-your-logs-in-dart-86881df05929
Use this link to generate models for your response

get data from internet and push to array flutter

So, here is my code.
Future<Album> fetchAlbum() async {
final response =
await http.get(Uri.https('jsonplaceholder.typicode.com', 'albums/1'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
//var data = jsonDecode(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
class Album {
final int userId;
final int id;
final String title;
Album({#required this.userId, #required this.id, #required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
I want to get Album values (userId, id, title) and push it to an array so i can do some math...
But i dont know how to do it, i manage to display the data on screen with Builder() method, but not acess it individually.
this should work!
Future<Album> fetchAlbum() async {
var response = await http.get('https;//jsonplaceholder.typicode.com' + '/albums/1');
if (response.statusCode == 200) {
return Album data = Album.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load album');
}
}
Album AlbumFromJson(String str) => TrueOrFalse.fromJson(json.decode(str));
String AlbumToJson(TrueOrFalse data) => json.encode(data.toJson());
class Album {
final int userId;
final int id;
final String title;
Album({#required this.userId, #required this.id, #required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
Map<String, dynamic> toJson() => {
"userId": userId,
"id": id,
"title": title,
};
}
I manage to make it work by creating a function and passing the values as parameter inside the factory.
Then, in the function "foo", i get the values and print it.
Future<Album> fetchAlbum() async {
final response =
await http.get(Uri.https('jsonplaceholder.typicode.com', 'albums/1'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
class Album {
final int userId;
final int id;
final String title;
Album({#required this.userId, #required this.id, #required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
foo(json['userId'], json['id'], json['title']);
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
void foo(userId, id, title) async {
final user = title;
print(user);
}

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<List<CamerasStreams>>' flutter API issue

How can I retrieve data from this link "https://185.86.145.54/cameras/all". I try to get data from API, but I got an issue look at picture below.
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<List>' flutter API issue
Can anyone explain me how can I retrieve data from this API?
Response class:
import 'dart:convert';
CamerasStreams camerasStreamsFromJson(String str) =>
CamerasStreams.fromJson(json.decode(str));
String camerasStreamsToJson(CamerasStreams data) => json.encode(data.toJson());
class CamerasStreams {
CamerasStreams({
this.empty,
});
List<Empty> empty;
factory CamerasStreams.fromJson(Map<String, dynamic> json) => CamerasStreams(
empty: List<Empty>.from(json["Камеры"].map((x) => Empty.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Камеры": List<dynamic>.from(empty.map((x) => x.toJson())),
};
}
class Empty {
Empty({
this.id,
this.info,
this.resComplex,
this.createDate,
this.link,
});
int id;
String info;
int resComplex;
DateTime createDate;
String link;
factory Empty.fromJson(Map<String, dynamic> json) => Empty(
id: json["id"],
info: json["info"],
resComplex: json["res_complex"],
createDate: DateTime.parse(json["create_date"]),
link: json["link"],
);
Map<String, dynamic> toJson() => {
"id": id,
"info": info,
"res_complex": resComplex,
"create_date": createDate.toIso8601String(),
"link": link,
};
}
Get function:
import 'dart:convert';
import 'dart:io';
import 'package:http/io_client.dart';
import '../AllData.dart';
Future<List<CamerasStreams>> getApplicationsAPICall() async {
bool trustSelfSigned = true;
HttpClient httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) => trustSelfSigned);
IOClient ioClient = new IOClient(httpClient);
String url = "https://185.86.145.54/cameras/all";
final response = await ioClient.get(
Uri.parse('$url'),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
//HttpHeaders.authorizationHeader: '',
},
);
var jsonResponse = json.decode(response.body);
print(jsonResponse);
return jsonResponse;
// return jsonResponse.map((job) => CamerasStreams.fromJson(job)).toList();
}

A value of type 'Resut' can't be returned from function'fetchPromotions' because it has a return type of Future<List<Promotions>>

I am fetching some data from an API, which returns a Json array, promotions_model.dart does all the parsing, but this error is showing up.
Error--
A value of type 'Result' can't be returned from function 'fetchPromotions' because it has a return type of 'Future<List>'.
can someone please tell me what i am doing wrong here. thanks
**promotions_model.dart**
import 'dart:convert';
Result resultFromJson(String str) => Result.fromJson(json.decode(str));
String resultToJson(Result data) => json.encode(data.toJson());
class Result {
Result({
this.code,
this.result,
});
final int code;
final List<Promotions> result;
factory Result.fromJson(Map<String, dynamic> json) => Result(
code: json["Code"],
result: List<Promotions>.from(
json["Result"].map((x) => Promotions.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Code": code,
"Result": List<dynamic>.from(result.map((x) => x.toJson())),
};
}
class Promotions {
Promotions({
this.id,
this.title,
this.description,
this.image,
});
final String id;
final String title;
final String description;
final String image;
factory Promotions.fromJson(Map<String, dynamic> json) => Promotions(
id: json["id"],
title: json["title"],
description: json["description"],
image: json["image"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"description": description,
"image": image,
};
}
**promotion-api.dart**
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:project/models/promotions_model.dart';
const key = {
'APP-X-RESTAPI-KEY': "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};
const API = 'http://111.111.11.1/project';
Future<List<Promotions>> fetchPromotions() async {
final response = await http.get(API + '/promotion/all', headers: key);
if (response.statusCode == 200) {
return resultFromJson(response.body); // This line is causing the error
} else {
print(response.statusCode);
}
}
The Error says it clearly. It needs Result as the return type.
You can something like this,
Result fetchPromotions() async {
final response = await http.get(API + '/promotion/all', headers: key);
Result result = null;
if (response.statusCode == 200) {
result = resultFromJson(response.body); // This line is causing the error
} else {
print(response.statusCode);
}
return result;
}
Hope you got an idea.
return resultFromJson(response.body);
This line returns a Result, not a List<Promotion>.