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);
}
Related
Im trying to make a searchbar that fetch data from mysql , but i have a problem that when i call data fetch function it returns
Instance of '_Future<List>'
this is my code
Future<List<Students>> getStudents(String id) async {
var url = 'http://localhost/getStudents.php';
final response = await http.post(Uri.parse(url), body: {
'id':id,
});
var res = jsonDecode(response.body)['fname'] as List;
if (response.statusCode == 200) {
return res.map((std) => Students.fromJson(std)).toList();
}else {
throw Exception('Failed to load shows');
}
}
my class :
class Students{
final int id;
final String fname;
final String sname;
final String tname;
const Students( {
required this.id,
required this.sname,
required this.tname,
required this.fname,
});
factory Students.fromJson(Map<String, dynamic> json) => Students(
id: json['Id'],
sname: json['secname'],
tname:json['thirdname'] ,
fname: json['firstname'],
);
}
getStudents is a future function and you need to await for it:
List<Students> result = await getStudents('');
I'm new to programming and currently learning JSON. I got this error when using Cubit to access the JSON:
RestaurantFailed(type 'Null' is not a subtype of type 'List<RestaurantModel>')
JSON Sample: https://restaurant-api.dicoding.dev/list
I'm trying to access the API and insert it to RestaurantModel.
this is my code:
restaurant_service.dart
class RestaurantService {
Future<List<RestaurantModel>> fetchAllData() async {
try {
Uri url = Uri.http('restaurant-api.dicoding.dev', '/list');
http.Response response = await http.get(url);
Map<String, dynamic> result = jsonDecode(response.body);
List<RestaurantModel> restaurants = result['restaurants'].forEach((json) {
return RestaurantModel.fromJson(json: json);
});
return restaurants;
} catch (e) {
rethrow;
}
}
}
restaurant_cubit.dart
class RestaurantCubit extends Cubit<RestaurantState> {
RestaurantCubit() : super(RestaurantInitial());
void fetchData() async {
try {
emit(RestaurantLoading());
List<RestaurantModel> restaurants =
await RestaurantService().fetchAllData();
emit(RestaurantSuccess(restaurants));
} catch (e) {
emit(RestaurantFailed(e.toString()));
}
}
}
restaurant_model.dart
class RestaurantModel {
final String id;
final String name;
final String description;
final String pictureId;
final String city;
final double rating;
String? address;
List<String>? categories;
List<String>? menus;
List<CustomerReviewModel>? customerReviews;
RestaurantModel({
required this.id,
required this.name,
required this.description,
required this.pictureId,
required this.city,
this.rating = 0.0,
this.address = '',
this.categories,
this.menus,
this.customerReviews,
});
factory RestaurantModel.fromJson({required Map<String, dynamic> json}) =>
RestaurantModel(
id: json['id'],
name: json['name'],
description: json['description'],
pictureId: json['pictureId'],
city: json['city'],
rating: json['rating'].toDouble(),
address: json['address'] ?? '',
categories: json['categories'] ?? [],
menus: json['menus'] ?? [],
customerReviews: json['customerReviews'] ?? [],
);
}
any feedback or input would be very appreciated! Cheers
The forEach should be replaced by map(...).toList() like the following code snippet:
List<RestaurantModel> restaurants = result['restaurants'].map((json) {
return RestaurantModel.fromJson(json: json);
}).toList();
This is because forEach returns void and it cannot be assigned to anything. On the other hand, map returns a Iterable<RestaurantModel> and it's just a matter of converting it to list with the toList() method.
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.');
}
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.
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>.