从api获取JSON列表数据

时间:2018-06-21 06:55:59

标签: dart flutter

我正在尝试从返回如下格式的json的端点获取问题列表:

[
  {
    "id": 1,
    "question": "text",
    "option1": "text",
    "option2": "text",
    "option3": "text",
    "option4": "text",
    "answer": "text"
  },
  {
    "id": 2,
    "question": "text",
    "option1": "text",
    "option2": "text",
    "option3": "text",
    "option4": "text",
    "answer": "text"
  }
]

在示例here之后,我有一个测验类:

class Quiz extends Object with _$QuizSerializerMixin {
  List<Question> questions;

  Quiz(this.questions);

  factory Quiz.fromJson(Map<String, dynamic> json) => _$QuizFromJson(json);
}

和问题类别:

class Question extends Object with _$QuestionSerializerMixin {

  final String question;
  final String option1;
  final String option2;
  final String option3;
  final String option4;
  final String answer;

  Question(
      {this.question,
      this.option1,
      this.option2,
      this.option3,
      this.option4,
      this.answer});

  factory Question.fromJson(Map<String, dynamic> json) =>
      _$QuestionFromJson(json);
}

函数定义为:

Future<Quiz> fetchQuiz() async {
  final response = await http.get('json_endpoint.placeholder/questions');

  if (response.statusCode == 200) {
    return Quiz.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to load quiz');
  }
}

如何将其传递给新的测验实例?这可能很明显,但我发现很难。

我尝试如下声明变量:

class QuizScreen extends StatefulWidget {
  @override
  _QuizScreenState createState() => _QuizScreenState();
}

class _QuizScreenState extends State<QuizScreen> {
Question question
String option1
...

Quiz quiz = quiz(fetchQuiz());

@override
void initState() {
super.initState();
question = quiz.nextQuestion;
option1 = question.option1;
...

Quiz quiz = Quiz(fetchQuiz());引发错误。

2 个答案:

答案 0 :(得分:2)

代码应类似于

Future foo() async {
  Quiz quiz = await fetchQuiz();
} 

fetchQuiz()返回一个Future<Quiz>并使用await来获取值,因为包含代码(在我的示例中为foo())的函数需要被设为async

答案 1 :(得分:1)

我认为您正在寻找FutureBuilderFuture完成后,您可以构建UI。如果snapshot.data,则结果将在snapshot.hasData == true中。

@override
  Widget build(BuildContext context) {
    return Scaffold(
        body: FutureBuilder<Quiz>(
      future: fetchQuiz(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return _buildQuiz(context, snapshot.data);
        } else if (snapshot.hasError) {
          return Text('${snapshot.error}');
        }
        return Center(child: CircularProgressIndicator());
      },
    ));
  }

void _buildQuiz(BuildContext context, Quiz quiz) {

}