Data not passing to second screen while using constructor - flutter

I was trying to send data got from a JSON response to a second screen from the main screen.
My widgets are placed in separate class files. I called a single API call to fetch all data from the API so that there won't be many API calls happening while opening the app.
But I can't pass the data to the second screen in arrMaincategories. What should I do?
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var arrBanner = [];
var arrImages = [];
var arrMainCategories = [];
#override
void initState() {
super.initState();
this.getBanner();
setState(() {});
}
getBanner() async {
String url = "https://www.clickxpress.in/api/";
var prefs = await SharedPreferences.getInstance();
var custID = prefs.getString('id');
var response = await http.post(Uri.encodeFull(url),
body: (<String, String>{
'type': "homepage",
'secKey': "2a067feaeb67fgh89fyrc6657654fhjj9714b2094818f",
'customerId': custID,
'geoLat': "55.2324",
'geoLong': "23.55556",
})); //for accepting only json response
setState(() {
Map<String, dynamic> map = json.decode(response.body);
var data = map["attributes"];
arrBanner = data['topBanner'];
arrMainCategories = data['mainCategories'];
if (arrBanner != null) {
for (var value in arrBanner) {
final image = value['imageUrl'];
arrImages.add(NetworkImage(image));
}
Called It to a new screen
NewCat(arrMainCategories: arrMainCategories),
trying to fetch on 2nd screen
class NewCat extends StatefulWidget {
NewCat({Key key, #required this.arrMainCategories}) : super(key: key);
final arrMainCategories;
#override
_NewCatState createState() => _NewCatState(arrMainCategories);
}
class _NewCatState extends State<NewCat> {
var arrMainCategories = [];
var arrCatImages = [];
var arrCatName = [];
_NewCatState(
arrMainCategories,
);
But the value is not coming here in the empty array. what to do?

Instead of using the Constructor, You Can also access the data by using this line of code
print(widget.arrMainCategories);
See this resource link for more details

use this
_NewCatState(
widget.arrMainCategories,
);
instead of this
_NewCatState(
arrMainCategories,
);

Related

Expected a value of type 'List', but got one of type '_JsonMap'

i'm new at flutter and i trying to call Django api and catch data from Django endpoint but keep getting this error ' Expected a value of type 'List', but got one of type '_JsonMap' '
so here is my UserAPI class :
class UserAPI{
int user;
String rank;
UserAPI({required this.user,required this.rank});
factory UserAPI.fromJson(Map<String,dynamic> json){
return UserAPI(user: json['user'], rank: json['rank']);
}
}
and my statefull widget:
class AllUser extends StatefulWidget {
const AllUser({Key? key}) : super(key: key);
#override
State<AllUser> createState() => _AllUserState();
}
class _AllUserState extends State<AllUser> {
late Future<List<UserAPI>> futureUsers;
final url= 'http://127.0.0.1:8000/api/v1/users/all-users';
Future<List<UserAPI>> fetchUserAPI() async{
http.Response response = await http.get(Uri.parse(url));
List users = json.decode(response.body);
return users.map((user)=>UserAPI.fromJson(user)).toList();
}
#override
void initState(){
super.initState();
futureUsers = fetchUserAPI();
}
.
.
.
if you can help me i'll be very grateful

Saving changing variable value in flutter

I want to save a variable's value that changes every 5 seconds then read it. I have already tried saving it to shared preferences then reading it but the problem with that was that the value was only saved one time and did not save the changes done to the variable. Is there a way to implement that in flutter?
class _MyAppState extends State<MyApp> {
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
_connect();
});
}
...
void predict(List<double> v) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<List<double>> L=List<List<double>>.filled(1, [0], growable: true);
L[0]=v;
...
String res=response.body;
Map R = json.decode(res);
var _list = R.values.toList();
print(res);
Proba= double.parse(_list[1]);
await prefs.setDouble('Proba', Proba);
}
....
class Page extends StatefulWidget {
Page({Key key, this.title}) : super(key: key);
final String title;
#override
PageState createState() => PageState();
}
class PageState extends State<Page> {
.....
Future<double> _getProbaFromSharedPref() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getDouble("Proba") ?? 0;
}
#override
void initState() {
super.initState();
Location1=_getCurrentLocation();
_getStringFromSharedPref();
_getProbaFromSharedPref().then((s) {
Value = s;
});
Future.delayed(Duration.zero, () {
_check();
});
}
}
In the code I tried saving the variable in sharedPreferences then reading it, but I have no clue on how to reload it everytime it changes.

How can I pass variable id to second screen in flutter?

I have two page and I want to use the variable 'id' in the second screen to fetch data from API.
What should I do?
Screen one: it's the product screen where user click on profile image and after that I get all information about user owner in the second screen.
Screen two: I display data for this user by id
NB: I get all the data by API
id is always Null
Screen one:
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(
id: id,
)),
);
// do something here
},
),
Screen two:
class UserProfile extends StatefulWidget {
final int id;
const UserProfile({Key key, #required this.id}) : super(key: key);
#override
_UserProfileState createState() => _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
#override
void initState() {
getprofile(id);
super.initState();
}
Future<List<dynamic>> getprofile(int id) async {
var response = await Network().getData('/auth/user/$id');
data = json.decode(response.body);
return data;
}
When you want to use a property from the StatefulWidget you need to use widget.propertyName. In your case it's widget.id
class _UserProfileState extends State<UserProfile> {
#override
void initState() {
getprofile(widget.id);
super.initState();
}
Future<List<dynamic>> getprofile(int id) async {
var response = await Network().getData('/auth/user/$id');
data = json.decode(response.body);
return data;
}
Either do the same that you did before,so pass the id as a parameter to the _UserProfileState class, so just call:
_UserProfileState(#required this.id) : super();
Another option to make variables available is to use the Provider widget

how to access to variable from StatefulWidget to State class flutter

I try to pass data from page one to page two data is pass OK but I have one problem now.
this is my code:
class SecondScreen extends StatefulWidget {
final int itemHolder ;
SecondScreen({Key key, #required this.itemHolder}) : super(key: key);
#override
State<StatefulWidget> createState() {
return new mainState();
}
}
class mainState extends State <SecondScreen> {
bool value = false ;
MyPreferences _myPreferences = MyPreferences();
#override
void initState() {
// TODO: implement initState
super.initState();
initial();
}
void initial() async {
setState(() {
});
}
final String apiURL = 'http://xxxxxxxxx/getFlowersList.php';
Future<List<Flowerdata>> fetchFlowers() async {
var response = await http.get(apiURL);
if (response.statusCode == 200) {
final items = json.decode(response.body).cast<Map<String, dynamic>>();
List<Flowerdata> listOfFruits = items.map<Flowerdata>((json) {
return Flowerdata.fromJson(json);
}).toList();
return listOfFruits;
}
else {
throw Exception('Failed to load data from Server.');
}
}
I try to use var (itemHolder ) in the link like that:
final String apiURL = 'http://xxxxxxx/getFlowersList.php?id=' +itemHolder;
but I get error:
Undefined name 'itemHolder'. Try correcting the name to one that is defined, or defining the name.
I can access to itemHolder. So how can I access to it?
try this:
...
String apiURL;
#override
void initState() {
super.initState();
apiURL = 'http://xxxxxxx/getFlowersList.php?id=' +widget.itemHolder.toString();
}
...
To use the variables declared in the SecondScreen you have to access it with the prefix 'widget' and the dot operator, not directly. Here is the code:
final String apiURL = 'http://xxxxxxx/getFlowersList.php?id=' + widget.itemHolder;
And when you make the variable final, you have to initialize it while declaration or through constructor else delete keyword final:

How to get id from StatefulWidget in State?

I want to load comments in my post here. For that I need to send post id to my HTTP get request. post id I sent from another page. but I want to assign that String id; value to final response = await http.get("http://$ip:$apiPort/solutions/$id"); here id in Flutter.
How can I do that?
to clear what I want
my code is
class Solutions extends StatefulWidget {
String id ;
final bool isEditMode;
Solutions({
this.id,
this.isEditMode,
});
#override
_SolutionsState createState() => _SolutionsState();
}
class _SolutionsState extends State<Solutions> {
List data;
var ip = Configuration.yourIp;
var apiPort = Configuration.yourApiPort;
Future<List> getData() async {
final response = await http.get("http://$ip:$apiPort/solutions/$id");
return json.decode(response.body);
}
#override
void initState() {
super.initState();
this.getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
Future<List> getData() async {
final response = await http.get("http://$ip:$apiPort/solutions/${widget.id}");
return json.decode(response.body);
}
This should to the trick.
From the State class (_SolutionState in your case), you can access the widget (Solution in your case) members by finding them in widget.
BONUS
Your id should be final, since StatefulWidget is marked as an immutable class, which means its members should all be final. You have surely a warning about this from your IDE.