Reputation: 1
New to the Dart Language and been trying to make an app, But i've been stuck on this problem for a while now and can't seem to solve it. I've been trying to read from the content from a Json file and use a random value generator to pick out which info form the Json to display,
ex
name: Roxxxer Email: [email protected]
name: Roxxxer1 Email: [email protected]
But every time I try to display any of these values I get this error:
This is the json class reader(?)
class Recept{
final String title;
final String body;
Recept({this.title, this.body});
factory Recept.fromJson(dynamic json){
return Recept( title: json['title'] as String,
body: json['body'] as String,
);
}
String toString() {
return '{ ${this.title}, ${this.body} }';
}
}
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:randomfood/Recept.dart';
import 'package:flutter/services.dart';
void main() {
runApp(
new MaterialApp(
home: new AwesomeButton()
)
);
}
class AwesomeButton extends StatefulWidget {
@override
Button createState() => new Button();
}
class Button extends State<AwesomeButton> {
String test;
void onPressed() {
setState(() {
//This is where the random generator goes in and give a new place in the json file
});
}
Future<String> LoadRecipesFromJson() async{
return await rootBundle.loadString('assets/test.json');
}
Future LoadRecipes() async{
String jsonString = await LoadRecipesFromJson();
final jsonResponse = json.decode(jsonString);
Recept recept = new Recept.fromJson(jsonResponse);
String ToString() {
return '${recept.title}';
}
test = ToString();
}
@override
void initState() {
super.initState();
LoadRecipes();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("Random Recipe Generator!"), backgroundColor: Colors.blueGrey),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Text(test, style: new TextStyle(color: Colors.black,fontStyle: FontStyle.italic, fontSize: 30.0, fontWeight: FontWeight.bold)),
new Padding(padding: new EdgeInsets.all(50.0)),
new RaisedButton(
child: new Text("Random Recept!", style: new TextStyle(color: Colors.white, fontStyle: FontStyle.italic, fontSize: 20.0)),
color: Colors.blueGrey,
onPressed: onPressed
)
]
)
)
)
);
}
}
Upvotes: 0
Views: 296
Reputation: 6161
Since you're using a StatefulWidget
you need to use the setState()
method to update variables, even though you're calling the function in initState
. The reason you have to is that you're using asynchronous data. initState
isn't going to wait around for the data so you have to update the state yourself. After you update the state, it will call the build
method again and rebuild the widget and your Text
widget will be using the new value from the test
variable.
Also, the new
keyword is optional as of Dart 2.0.
CORRECTION: You can put a function inside of another function.
Future<void> LoadRecipes() async{
String jsonString = await LoadRecipesFromJson();
final jsonResponse = json.decode(jsonString);
Recept recept = new Recept.fromJson(jsonResponse);
setState(() {
test = recept.title;
});
}
Upvotes: 1
Reputation: 3186
The variable test may not have a value in the beginning as you are asynchronously loading value into test variable. While giving the test variable inside Text(test) widget if test is null, It'll give an error that you are getting right now. So to prevent this from happening just make a slight change in your code change
This
new Text(test, style: new TextStyle(color: Colors.black,fontStyle: FontStyle.italic, fontSize: 30.0, fontWeight: FontWeight.bold)),
to
new Text(test??"Loading", style: new TextStyle(color: Colors.black,fontStyle: FontStyle.italic, fontSize: 30.0, fontWeight: FontWeight.bold)),
Now if the value of test is null you'll get Loading as the text otherwise whatever is the value of the test.
Upvotes: 1