How can I fetch and use data with this design in flutter - flutter

I have this design, I created it and put the data manually, the question is how can I get the data in the image and it is from this website (https://jsonplaceholder.typicode.com/posts) and display it in the same design

var url = Uri.parse("https://jsonplaceholder.typicode.com/posts");
var response = await http.get(url);
if (response.statusCode == 200) {
var responseJson = jsonDecode(response.body);
responseJson as List;
return responseJson.map((e) => YourModel.fromJson(e)).toList();
}

Firstly, you can paste your JSON in the link below, click convert and get your Dart classes for free.
Secondly, you can copy the result which is named JsonPlaceHolderResponse and create a new file in your project, and paste the result there.
Finally, you can use this code to get your data from defined API:
import 'package:http/http.dart';
Future<JsonPlaceHolderResponse?> getData(String url) async {
final _response = await Client().get(
url
);
if (_response.successResponse) {
final _json = jsonDecode(_response.body);
return JsonPlaceHolderResponse.fromJson(_json);
} else {
return null;
}
return null;
}
extension ResponseExtension on Response {
bool get hasWrongCredentials => statusCode == 422;
bool get tooManyRequests => statusCode == 429;
bool get successResponse => statusCode >= 200 && statusCode < 300;
}

Related

not able to access json file in flutter api call

I want to use JSON from this link https://howtodoandroid.com/movielist.json.
This is my code where I want to call API from the above link
Future getMovieList() async {
final response = await http.get(Uri.parse("https://howtodoandroid.com/movielist.json"));
if (response.statusCode == 200) {
allMovielist = jsonDecode(response.body);
}
}
i got error "failed to load response data: no data found for resource with given identifier"
Future<List<YourModel>> getMovieList() async {
final response = await http.get(Uri.parse("https://howtodoandroid.com/movielist.json"));
if (response.statusCode == 200) {
/// On first the data will get is always unassigned or just dynamic
/// which cant be identify
final List<dynamic> list = jsonDecode(response.body);
/// try to print or log the data if the data goes to status 200 and able
/// to see it
log(list.map((e) => e).toList().toString());
/// this one will return the indicate assigned data
return list.map((e)=> YourModel.fromJson(e)).toList();
} else{
return [];
}
}
If you are trying this on the web run this command flutter run -d chrome --web-renderer html
if you still get a CROS error disable the web security.
1- Go to flutter\bin\cache and remove a file named: flutter_tools.stamp
2- Go to flutter\packages\flutter_tools\lib\src\web and open the file chrome.dart.
3- Find '--disable-extensions'
4- Add '--disable-web-security'
I get this answer from this link
or consider this package also
Example Code
Future getMoviesList() async {
var headers = <String, String>{'Content-Type': 'application/json'};
var url = Uri.parse('https://howtodoandroid.com/movielist.json');
var response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
var result = json.decode(response.body);
print(result);
return result;
}
}

Replace "map" method to traditional loops in dart when fetching data from API

I was wondering if there is a different approach more efficient to include data from a json API to a simple list.
As I read in some posts, map method is the most time/resource consuming in comparation with the traditional for/while loop in Dart.
Currently I use this snippet to fetch my data:
Future<List<dynamic>> fetchData(url) async {
var client = http.Client();
final response = await client.get(Uri.parse(url));
await Future.delayed(Duration(seconds:2));
if (response.statusCode == 200) {
var jsonDecoded = json.decode(response.body);
BreedList = jsonDecoded.map((data) => DogClass.fromJson(data)).toList();
glossarList = BreedList;
return BreedList;
} else {
throw Exception('Failed to load data');
}
}
I tried this approach:
Future<List<dynamic>> fetchDataFor(url) async {
var client = http.Client();
final response = await client.get(Uri.parse(url));
await Future.delayed(Duration(seconds:2));
if (response.statusCode == 200) {
var jsonDecoded = json.decode(response.body);
for (var k in jsonDecoded.keys){
BreedList.add({jsonDecoded[k]});
}
return BreedList;
} else {
throw Exception('Failed to load data');
}
}
But it returns the error: Class List has no instance getter 'keys'.
So, what would be the equivalent for the "map" method ?
You can use collection-for to perform a straightforward transformation of .map calls.
var result = iterable.map((element) => transform(element)).toList();
can be replaced with:
var result = [for (var element in iterable) transform(element)];
So in your case:
BreedList = jsonDecoded.map((data) => DogClass.fromJson(data)).toList();
can become:
BreedList = [for (var data in jsonDecoded) DogClass.fromJson(data)];

Flutter await for another method complete

I want to check if new update is available for my application or not. if update is available redirect user to UpdateScreen and if update is not available get the user info and redirect to HomeScreen
_check() async {
await _checkForUpdate();
await _getUserData(token);
}
_checkForUpdate() async {
print('check for update');
var url = Uri.parse(Endpoints.mainData);
var response = await http.get(url);
var jsonResponse = convert.jsonDecode(response.body);
var data = jsonResponse['data'];
int lastVersionCode = data['lastVersionCode'];
if(lastVersionCode > Data.versionCode){
redirectToScreen(context, UpdateScreen());
}
}
_getUserData(String token) async {
print('get user data');
var url = Uri.parse(Endpoints.accountInfo + '/?token=' + token);
var response = await http.get(url);
var jsonResponse = convert.jsonDecode(response.body);
var data = jsonResponse['data'];
//setup user data in my app
redirectToScreen(context, HomeScreen());
When I run my application two methods( _checkForUpdate, _getUserData) get fired and in output I the get following message that i printed:
check for update
get user data
and i see Update screen for 1 second and then user is redirect to HomeScreen.
i want to skip running the other codes after _checkForUpdate redirect user to UpdateScreen
return a bool whether there is an update available and use it to skip other methods:
_check() async {
bool needsUpdate = await _checkForUpdate();
if (!needsUpdate)
await _getUserData(token);
}
Future<bool> _checkForUpdate() async {
print('check for update');
var url = Uri.parse(Endpoints.mainData);
var response = await http.get(url);
var jsonResponse = convert.jsonDecode(response.body);
var data = jsonResponse['data'];
int lastVersionCode = data['lastVersionCode'];
if (lastVersionCode > Data.versionCode) {
redirectToScreen(context, UpdateScreen());
return true;
}
return false;
}

How to mix 2 json response to 1 list in Flutter

How to mix 2 json response to 1 list in flutter?
I have 2 json https://api.thecatapi.com/v1/images/search?limit=10&page=1&order=Desc and https://catfact.ninja/facts?limit=10.
Need create 1 model list with ['catimageurl'] from first and ['catfact'] from second .
I try this code but catqfact return null
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class CatsModel {
final String caturl;
final String catqfact;
CatsModel({this.caturl, this.catqfact});
factory CatsModel.fromJson(Map<String, dynamic> jsonData) {
return CatsModel(caturl: jsonData['url'], catqfact: jsonData['fact']);
}
}
Future<List<CatsModel>> getCat() async {
var url = Uri.parse(
'https://api.thecatapi.com/v1/images/search?limit=10&page=1&order=Desc');
var response = await http.get(url);
if (response.statusCode == 200) {
List cats = json.decode(response.body);
return cats.map((cat) => CatsModel.fromJson(cat)).toList();
} else
throw Exception('Json data download error');
}
Future<List<CatsModel>> getCatFact() async {
var url = Uri.parse('https://catfact.ninja/facts?limit=10');
var response = await http.get(url);
if (response.statusCode == 200) {
List catsFacts = json.decode(response.body);
return catsFacts.map((cat) => CatsModel.fromJson(cat)).toList();
} else
throw Exception('Json data download error');
}
you just need one function, since you have to combine data anyway.
Future<List<CatsModel>> getCatData() async {
var imagesUri = Uri.parse('https://api.thecatapi.com/v1/images/search?limit=10&page=1&order=Desc');
var factsUri = Uri.parse('https://catfact.ninja/facts?limit=10');
var imagesResponse = await http.get(imagesUri);
var factsResponse = await http.get(factsUri);
if (imagesResponse.statusCode == 200 && factsResponse.statusCode == 200) {
List images = json.decode(imagesResponse.body);
List facts = json.decode(factsResponse.body)['data'];
List<CatsModel> cats = [];
for (int i = 0; i < images.length; i++) {
cats.add(CatsModel(caturl: images[i]['url'], catqfact: facts[i]['fact']));
}
return cats;
} else
throw Exception('Json data download error');
}
Here is the pastebin link for the full working code
This is what it looks like.
Comment, if you feel you have doubt about any part. I'll explain.

Flutter : How to add more json data to existing Model Class?

I have a scenario where the following function is called again and again whenever the user hits the "Load More" button.
The problem I'm facing is, that it replaces previously loaded data with a new one. Instead, it should add to the bottom of the Listview.Builder
Future fetchData() async{
var url = "url_goes_here";
final response = await http.get(url);
if (response.statusCode == 200) {
var resBody = jsonDecode(response.body);
var data = resBody['data'] as List;
if (data.isNotEmpty) {
setState(() {
listVariable = data
.map<ModelClass>((json) => ModelClass.fromJson(json))
.toList();
});
}
}
}
List<ModelClass> listVariable =List<ModelClass>(); //describe the object that way.
--------and---------
data.map<ModelClass>((json) {
listVariable.add(ModelClass.fromJson(jsonn));
} )).toList();
You should add received data to your listVariable, not assign a new value. Try this code:
final listVariable = <ModelClass>[];
...
Future fetchData() async {
var url = "url_goes_here";
final response = await http.get(url);
if (response.statusCode == 200) {
var resBody = jsonDecode(response.body);
var data = resBody['data'] as List;
if (data.isNotEmpty) {
final list = data.map<ModelClass>((json) => ModelClass.fromJson(json));
setState(() {
listVariable.addAll(list); // HERE: addAll() instead of assignment
});
}
}
}
I was able to figure out answer myself.
setState(() {
listVariable.addAll(data
.map<ModelClass>((json) => ModelClass.fromJson(json))
.toList();
}));
#Mol0ko and #hasan karaman both are right but #Mol0ko
Makes better sense when you have a set of data to addAll to existing data.