Bird
Raised Fist0
Fluttermobile~20 mins

Model classes from JSON in Flutter - Mini App: Build & Ship

Choose your learning style10 modes available
Build: User Profile Screen
This screen shows user information loaded from a JSON string. You will create model classes to parse the JSON and display the user's name and email.
Target UI
-------------------------
|      User Profile      |
|-----------------------|
| Name:                 |
| Email:                |
|                       |
| [Refresh Data]        |
-------------------------
Create a Dart model class User with fields: name (String), email (String)
Add a factory constructor to parse User from JSON string
Display the user's name and email on the screen
Add a Refresh Data button that reloads the user data from the JSON
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'dart:convert';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: UserProfileScreen(),
    );
  }
}

class UserProfileScreen extends StatefulWidget {
  const UserProfileScreen({super.key});

  @override
  State<UserProfileScreen> createState() => _UserProfileScreenState();
}

class _UserProfileScreenState extends State<UserProfileScreen> {
  late User user;

  @override
  void initState() {
    super.initState();
    // TODO: Initialize user from JSON
  }

  void _refreshUser() {
    setState(() {
      // TODO: Reload user from JSON
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('User Profile')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Name: '), // TODO: Show user name
            const SizedBox(height: 8),
            Text('Email: '), // TODO: Show user email
            const Spacer(),
            ElevatedButton(
              onPressed: _refreshUser,
              child: const Text('Refresh Data'),
            ),
          ],
        ),
      ),
    );
  }
}

// TODO: Create User model class with fromJson factory
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
Flutter
import 'package:flutter/material.dart';
import 'dart:convert';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: UserProfileScreen(),
    );
  }
}

class UserProfileScreen extends StatefulWidget {
  const UserProfileScreen({super.key});

  @override
  State<UserProfileScreen> createState() => _UserProfileScreenState();
}

class _UserProfileScreenState extends State<UserProfileScreen> {
  late User user;

  final String userJson = '{"name": "Alice Johnson", "email": "alice@example.com"}';

  @override
  void initState() {
    super.initState();
    user = User.fromJson(jsonDecode(userJson));
  }

  void _refreshUser() {
    setState(() {
      user = User.fromJson(jsonDecode(userJson));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('User Profile')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Name: ${user.name}'),
            const SizedBox(height: 8),
            Text('Email: ${user.email}'),
            const Spacer(),
            ElevatedButton(
              onPressed: _refreshUser,
              child: const Text('Refresh Data'),
            ),
          ],
        ),
      ),
    );
  }
}

class User {
  final String name;
  final String email;

  User({required this.name, required this.email});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      name: json['name'] as String,
      email: json['email'] as String,
    );
  }
}

We created a User class with name and email fields. The fromJson factory constructor converts a JSON map into a User object.

In the stateful widget, we store the JSON string and parse it in initState to initialize the user. The _refreshUser method reloads the user data from the same JSON string and updates the UI.

The UI shows the user's name and email using string interpolation inside Text widgets. The Refresh Data button triggers the reload.

Final Result
Completed Screen
-------------------------
|      User Profile      |
|-----------------------|
| Name: Alice Johnson    |
| Email: alice@example.com|
|                       |
| [Refresh Data]        |
-------------------------
Tapping 'Refresh Data' reloads the user data from JSON and updates the displayed name and email.
Stretch Goal
Add error handling for invalid JSON data and show an error message on the screen.
💡 Hint
Use try-catch around jsonDecode and display a Text widget with error if parsing fails.

Practice

(1/5)
1. What is the main purpose of a model class when working with JSON in Flutter?
easy
A. To handle user input events
B. To display UI elements on the screen
C. To convert JSON data into Dart objects and back
D. To manage app navigation between screens

Solution

  1. Step 1: Understand the role of model classes

    Model classes are designed to represent data structures in Dart that match JSON data.
  2. Step 2: Identify the purpose related to JSON

    They convert JSON strings into Dart objects and convert Dart objects back to JSON for easy data handling.
  3. Final Answer:

    To convert JSON data into Dart objects and back -> Option C
  4. Quick Check:

    Model class = JSON conversion [OK]
Hint: Model classes handle JSON to Dart object conversion [OK]
Common Mistakes:
  • Confusing model classes with UI widgets
  • Thinking model classes manage navigation
  • Assuming model classes handle user input
2. Which of the following is the correct syntax for a factory constructor named fromJson in a Dart model class?
easy
A. factory Model.fromJson(Map json) { return Model(json['id']); }
B. Model.fromJson(Map json) { return Model(json['id']); }
C. factory Model.fromJson(Map json) { Model(json['id']); }
D. Model.fromJson(Map json) => Model(json['id']);

Solution

  1. Step 1: Recall factory constructor syntax

    In Dart, a factory constructor uses the keyword 'factory' and returns an instance, often with a return statement.
  2. Step 2: Check each option for correct syntax

    factory Model.fromJson(Map json) { return Model(json['id']); } correctly uses 'factory', has the parameter, and returns a new Model instance inside braces.
  3. Final Answer:

    factory Model.fromJson(Map json) { return Model(json['id']); } -> Option A
  4. Quick Check:

    Factory constructor syntax = factory Model.fromJson(Map json) { return Model(json['id']); } [OK]
Hint: Factory constructors need 'factory' keyword and return statement [OK]
Common Mistakes:
  • Omitting the 'factory' keyword
  • Not returning an instance
  • Using arrow syntax without 'factory'
3. Given this Dart model class snippet, what will print(user.name); output?
class User {
  final String name;
  User(this.name);

  factory User.fromJson(Map json) {
    return User(json['name']);
  }
}

void main() {
  final json = {'name': 'Alice'};
  final user = User.fromJson(json);
  print(user.name);
}
medium
A. null
B. Alice
C. User Instance
D. Error: No such method

Solution

  1. Step 1: Understand fromJson factory usage

    The factory constructor takes the JSON map and extracts the 'name' value, passing it to the User constructor.
  2. Step 2: Trace the print statement

    The user object has name set to 'Alice', so printing user.name outputs 'Alice'.
  3. Final Answer:

    Alice -> Option B
  4. Quick Check:

    JSON 'name' value = printed name [OK]
Hint: fromJson sets fields from JSON keys [OK]
Common Mistakes:
  • Expecting print to show object instead of field
  • Confusing factory constructor with normal constructor
  • Assuming null if key missing
4. Identify the error in this Dart model class code for JSON parsing:
class Product {
  final int id;
  final String name;

  Product(this.id, this.name);

  factory Product.fromJson(Map json) {
    return Product(json['id'], json['title']);
  }
}
medium
A. The JSON key 'title' does not match the field 'name'
B. The constructor parameters are in wrong order
C. Missing semicolon after constructor
D. Factory constructor should not return Product instance

Solution

  1. Step 1: Compare JSON keys with class fields

    The class has a field 'name' but the factory uses 'json['title']' which does not match.
  2. Step 2: Understand impact of key mismatch

    This causes the 'name' field to get null or wrong value, leading to incorrect data mapping.
  3. Final Answer:

    The JSON key 'title' does not match the field 'name' -> Option A
  4. Quick Check:

    JSON keys must match field names [OK]
Hint: JSON keys must match model field names exactly [OK]
Common Mistakes:
  • Using wrong JSON keys
  • Ignoring field and parameter order
  • Thinking factory can't return instance
5. You have a JSON list of users: [{'id':1,'name':'Bob'},{'id':2,'name':'Eve'}]. How do you convert this list into a Dart list of User objects using a model class with fromJson factory?
hard
A. User.fromJson(jsonList[0])
B. User.fromJson(jsonList)
C. jsonList.forEach((json) => User.fromJson(json))
D. jsonList.map((json) => User.fromJson(json)).toList()

Solution

  1. Step 1: Understand JSON list to Dart list conversion

    Each JSON map in the list must be converted to a User object using fromJson.
  2. Step 2: Use map and toList for conversion

    Using map applies fromJson to each item, and toList collects results into a Dart list.
  3. Final Answer:

    jsonList.map((json) => User.fromJson(json)).toList() -> Option D
  4. Quick Check:

    Map each JSON to User, then toList [OK]
Hint: Use map + fromJson + toList to convert JSON list [OK]
Common Mistakes:
  • Passing whole list to fromJson expecting batch conversion
  • Using forEach without collecting results
  • Converting only first item
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard