I am getting some errors in flutter - flutter

I took a course about Flutter from udemy. I've come to the Firebase part. However, I am getting errors in this part. I am getting an error even though I type exactly the same. I think I got error like this because there are updates in Flutter language. I'm sorry my English is bad. Thank you in advance for helping me.
enter image description here
main.dart
import 'dart:html';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fire_base1/user.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<List<User>> getData() async {
final res = await FirebaseFirestore.instance.collection("users").get();
List<User> myresult = <User>[];
for (int i = 0; i < res.docs.length; i++) {
User user = new User(
name: res.docs[i]["name"],
last_name: res.docs[i]["last_name"],
email: res.docs[i]["email"]);
myresult.add(user);
}
return myresult;
}
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FireBase"),
),
body: FutureBuilder(
future: Firebase.initializeApp(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text("Veritabanına bağlanırken bir hata meydana geldi");
}
if (snapshot.connectionState == ConnectionState.done) {
return FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].name +
" " +
snapshot.data[index].last_name),
subtitle: Text(snapshot.data[index].email),
);
},
);
} else {
return SizedBox();
}
},
);
}
return Center(
child: CircularProgressIndicator(),
);
},
));
}
}
user.dart
class User {
String name;
String last_name;
String email;
User({required this.name, required this.last_name, required this.email});
Map<String, dynamic> toMap() {
Map<String, dynamic> data = new Map<String, dynamic>();
data["name"] = name;
data["last_name"] = last_name;
data["email"] = email;
return data;
}
}

Please always copy/paste the error your IDE or your runtime shows in here. Screenshots won't help much.
Anyways, by looking at your image it seems like that data is a nullable variable, and therefore accessing it throws a compile-time error because of sound null safety.
You have two options:
Riskier and inelegant hasty option: just add a bang operator ! to perform a null check, in which you're telling Dart that you're sure that data isn't null
Robust, elegant, well-thought option: learn and use the null-aware operators such as ?., ?? and ??=.
For example in the following snippet (by looking at your code):
itemCount: snapshot.data.length
I'd do something like:
itemCount: snapshot.data?.length ?? 0
Which solution might not be correct - it depends on your business logic, i.e. what you want to do.
The inelegant option would be something like
if (data != null)
itemCount: snapshot.data!.length
Which can lead to unexpected runtime errors in the long run.

Related

NoSuchMethodError: 'cast' with dart language

i'm following flutter offical docs to parse JSON in the background with the rest api from themoviedb. I get this following error when trying to show the list of movies
the api link : https://api.themoviedb.org/3/trending/movie/week?api_key=$apiKey
json data
app.dart'
simplify main.dart and isolate parsing using compute
import 'dart:convert';
import 'package:flutter/material.dart';
import 'models/movie_response.dart';
import 'package:auth_request/api_key.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
Future<List<Movie>> fetchMovies(http.Client client) async {
final response = await client
.get(Uri.parse('https://api.themoviedb.org/3/trending/movie/week?api_key=$apiKey'));
// Use the compute funtion to run fetchMovies in a separate isolate
return compute(parseMovies, response.body);
}
// A function that converts a response body into a List<Movie>.
List<Movie> parseMovies(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Movie>((json) => Movie.fromJson(json)).toList();
}
class MovieApp extends StatefulWidget {
const MovieApp({super.key});
#override
MovieAppState createState() => MovieAppState();
}
class MovieAppState extends State<MovieApp> {
late Future<Movie> futureAlbum;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MovieDB List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('MovieDB List'),
),
body: Center(
child: FutureBuilder<List<Movie>>(
future: fetchMovies(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('${snapshot.error}');
} else if (snapshot.hasData) {
return MoviesList(movies: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
);
}
}
//
class MoviesList extends StatelessWidget {
const MoviesList({super.key, required this.movies});
final List<Movie> movies;
#override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemBuilder: (context, index) {
return Image.network(movies[index].original_title);
},
);
}
}
movie.dart
Parse and convert the JSON into a list of movies with the help of map and factory
class Movie {
final String original_title;
final String overview;
final String poster_path;
final String release_date;
const Movie({
required this.original_title,
required this.overview,
required this.poster_path,
required this.release_date,
});
factory Movie.fromJson(Map<String, dynamic> json) {
return Movie(
original_title: json['original_title'],
overview: json['overview'],
poster_path: json['poster_path'],
release_date: json['release_date'],
);
}
}
change this:
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
to
final parsed = jsonDecode(responseBody)['results'];

Flutter: Missing concrete implementation of 'State.build'

I am receiving an error on line 16 : class _HomePageState extends State {
I have a build function already in a widget that I have posted below, and when I try to implement a build in the _HomePageState the code below is unable to run. Im unsure on how to fix this error and would appreciate any help!
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MaterialApp(
home: HomePage(),
debugShowCheckedModeBanner: false,
));
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future getUserData() async {
var response = await http.get(Uri.parse(
'https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m'));
var jsonData = jsonDecode(response.body);
List users = (response.body as List?)
?.map((u) => User(
u['hourly'],
u['time'],
u['temperature_2m'],
u['longitude'],
u['generationtime_ms'],
u['hourly_units'],
u['latitude']))
.toList() ??
[];
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Rangers Tool'),
),
body: Center(
child: Card(
child: FutureBuilder(
future: getUserData(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(child:
CircularProgressIndicator());
} else {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(snapshot.data[i].longitude),
subtitle: Text(snapshot.data[i].latitude),
);
});
}
},
))),
);
}
getUserData() {}
class User {
final String? hourly,
time,
temperature_2m,
longitude,
generationtime_m,
hourly_units,
latitude;
User(this.longitude, this.latitude, this.hourly, this.time,
this.temperature_2m, this.generationtime_m, this.hourly_units);
}
Your build method is outside the scope of your state class.

FutureBuilder - How to iterate through a list of Futures

I want to fetch price data of trading pairs specified inpriceList from the public Binance API and create a dynamic List of Card widgets using API response.
I am failing at this step as the future argument of FutureBuilder does not accept the list of Futures : List<Future<PriceListItem>> pliList
Thank you.
My code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class PriceListItem {
final String pair;
final String price;
PriceListItem({
required this.pair,
required this.price,
});
factory PriceListItem.fromJson(Map<String, dynamic> json) {
return PriceListItem(
pair: json['symbol'],
price: json['price'],
);
}
}
class _HomePageState extends State<HomePage> {
List<String> pairList = [
"USTBUSD",
"USTUSDT",
"USDCBUSD",
"USDCUSDT",
"BUSDUSDT",
"BTCBUSD",
"USTBTC",
"BTCUSDT",
"BTCUSDC",
];
late Future<PriceListItem> pli;
late List<Future<PriceListItem>> pliList;
Future<PriceListItem> fetchPrice(String ticker) async {
final response = await http.get(Uri.parse(
"https://api.binance.com/api/v3/ticker/price?symbol=$ticker"));
if (response.statusCode == 200) {
return PriceListItem.fromJson(jsonDecode(response.body));
} else {
throw Exception("Failed to fetch price data.");
}
}
#override
void initState() {
pliList = [];
for (int i = 0; i < pairList.length; i++) {
pli = fetchPrice(pairList[i]);
pliList.add(pli);
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("price tracker"),
),
body: Column(
children: [
FutureBuilder<PriceListItem>(
future: pliList, //The argument type 'List<Future<PriceListItem>>' can't be assigned to the parameter type 'Future<PriceListItem>?'.dartargument_type_not_assignable
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: 2,
physics: const ScrollPhysics(),
padding: const EdgeInsets.all(8),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(snapshot.data!.price),
subtitle: Text(snapshot.data!.pair),
trailing: const Icon(Icons.currency_bitcoin),
onTap: () {},
),
);
},
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
)
],
),
);
}
}
Do it like this this:
FutureBuilder<List<PriceListItem>>(
future: Future.wait(pliList),
builder: (context, snapshot) {
}
https://api.flutter.dev/flutter/dart-async/Future/wait.html

Flutter 'List<Post>' has no instance getter 'lenght'

I'm new to flutter. I am getting an error like this, can you help me?
I've been stuck in http for json for 5 days, the codes in the source don't work. :( L
It says list not entered but when I enter it does not accept it.
I don't know on which line the problem is, but I got a warning like.
"The following NoSuchMethodError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#447cc):"
enter image description here
enter image description here
// To parse this JSON data, do
//
// final post = postFromJson(jsonString);
import 'dart:convert';
Post postFromJson(String str) => Post.fromJson(json.decode(str));
String postToJson(Post data) => json.encode(data.toJson());
class Post {
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
int userId;
int id;
String title;
String body;
factory Post.fromJson(Map<String, dynamic> json) => Post(
userId: json["userId"],
id: json["id"],
title: json["title"],
body: json["body"],
);
Map<String, dynamic> toJson() => {
"userId": userId,
"id": id,
"title": title,
"body": body,
};
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:json_http_place_holder/post.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future getData = Future(() => null);
var con = Uri.parse("https://jsonplaceholder.typicode.com/posts");
Future<List<Post>> fetchPost() async {
List<Post> result = <Post>[];
final response = await http.get(con);
if (response.statusCode == 200) {
List listPost = jsonDecode(response.body);
for (int i = 0; i < listPost.length; i++) {
Post item = Post.fromJson(listPost[i]);
result.add(item);
}
}
return result;
}
#override
void initState() {
// TODO: implement initState
super.initState();
getData = fetchPost();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter HTTP json',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: FutureBuilder(
future: getData,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.none) {
return const Center(
child: Text("Bir hata meydana geldi"),
);
} else if (snapshot.connectionState == ConnectionState.done) {
return ListView.separated(itemBuilder: (context,index){
return ListTile(
leading: Icon(Icons.local_post_office),
title: Text(snapshot.data[index].title),
subtitle: Text(snapshot.data[index].body),
);
},separatorBuilder: (context,index)=>Divider(),
itemCount: snapshot.data.lenght,
);
}
//var d =jsonDecode(snapshot.data.body);
return Container();
},
),
),
);
}
}
You did not spell length well.
The error tells No such method on list lenght
The correct spelling for getting the method is .length
Change
itemCount: snapshot.data.lenght,
to
itemCount: snapshot.data.length,
In your main.dart,
FutureBuilder => separatorBuilder =>
itemCount: snapshot.data.lenght,
Change the itemCount from that to :
itemCount: snapshot.data.length,

Flutter FutureBuilder snapshot returns Instance of 'Object' instead of data

i am new to flutter and trying to display data from a http post
referencing from [1]https://flutter.dev/docs/cookbook/networking/background-parsing and [2]https://flutter.dev/docs/cookbook/networking/fetch-data
i tried to display data on a futurebuilder but it keeps displaying this from the Text('${snapshot.data}')
[Instance of 'DashBoardBanner', Instance of 'DashBoardBanner', Instance of 'DashBoardBanner']
Builder
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<List<DashBoardBanner>> futureBanner;
#override
void initState() {
super.initState();
futureBanner = getBannerDataFromServer();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ListView(
children: [
Card(
child: FutureBuilder(
future: getBannerDataFromServer(),
builder: (context,snapshot){
if(snapshot.connectionState == ConnectionState.done){
if (snapshot.hasData) {
return Text('${snapshot.data}');
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
}
return const CircularProgressIndicator();
},
),
)
],
)),
);
}
}
Class and postreq
class DashBoardBanner {
final String MsgId;
final String MsgKey;
final String MsgPic;
const DashBoardBanner(
{required this.MsgId, required this.MsgKey, required this.MsgPic});
factory DashBoardBanner.fromJson(Map<String, dynamic> json) {
return DashBoardBanner(
MsgId: json['MsgId'] as String,
MsgKey: json['MsgKey'] as String,
MsgPic: json['MsgPic'] as String,
);
}
}
Future<List<DashBoardBanner>> getBannerDataFromServer() async {
final queryParameters = {
"ApiFunc": 'Banner',
"UserKey": getDeviceKey(),
"Token": getDeviceToken(),
"SubmitContent": json.encode({"MobileNo": getMobileNo1()})
};
final response = await http.post(
Uri.http('somesite.net', '/capi.aspx', queryParameters),
);
if (response.statusCode == 200) {
Map<String, dynamic> data = jsonDecode(response.body);
final splitoff = jsonEncode(data['RespContent']);
return compute(parseBanner, splitoff);
} else {
throw Exception('Failed to load Data');
}
}
List<DashBoardBanner> parseBanner(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed
.map<DashBoardBanner>((json) => DashBoardBanner.fromJson(json))
.toList();
}
Edit : i rebuilt the file replicating reference[1] and it finally displayed the data i needed, it seems the issue stem from not having this 2nd widget which return the obj back , however how do i combine the 2nd build widget into the first without needing the whole widget as having a whole build widget to return 1 line seems pointless?
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body:Container(
child: FutureBuilder<List<DashBoardBanner>>(
future: getBannerDataFromServer(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('An error has occurred!'),
);
} else if (snapshot.hasData) {
print(snapshot.data!.length);
return DashBoardBannersList(dashboardBanners: snapshot.data!); <--- original issue due to not having this
} else {
return CircularProgressIndicator();
}
},
),
),
);
}
}
class DashBoardBannersList extends StatelessWidget {
const DashBoardBannersList({Key? key, required this.dashboardBanners}) : super(key: key);
final List<DashBoardBanner> dashboardBanners;
#override
Widget build(BuildContext context) {
return Text(dashboardBanners[0].MsgId);
}
}
This error is caused because of the sound null safety
snapshot.data might be null for some requests so you can't access the array at a certain index cause it can be null.
If you know for sure snapshot.data exists you can use the ! operator to tell dart the variable is not null for sure like that:
snapshot.data![index];
You can also check if the data is null before accessing it like that:
if (snapshot.data != null) {
// do something with snapshot.data[index]
}
I recommed to read more about sound null safety here
Check the Firestore docs.
Inside snapshot.data, there's docs (every document of your collection).
The code is from there:
#override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['full_name']),
subtitle: Text(data['company']),
);
}).toList(),
);
},
);
}
The code above shows how to convert every doc (type DocumentSnapshot) to a JSON format (that can be represented with Map<String, dynamic>). To access to the doc id, you'll access with document.id, because it isn't inside the document.data() method.
You wanna retrieve a list of DashBoardBanner but you forget initialize the futurebuilder by adding a ListView.builder().
Try to use the following code idea :
FutureBuilder(
future: getBannerDataFromServer(http.Client()),
builder: (context, AsyncSnapshot snapshot) {
print(snapshot.hasData);
if (snapshot.hasError) {
return CircularProgressIndicator();
} else if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, int index) {
var data = snapshot.data![index];
return DashBoardBannersList(dashboardBanners: data);
},),
),},
},)