Menu
CoddyTech

JSON Values and as

Part of the Data and the Network section of Coddy's Flutter journey. Lesson 16 of 27.

A value from a JSON map is dynamic. Dart does not know what it is, so it does not check what you do with it, and the editor cannot help you. You know what the server sends: age is a number, isPro is true or false. Say so with as:

final age = user['age'] as int;
final isPro = user['isPro'] as bool;

as checks the value right there. From then on age is an int and isPro is a bool, and Dart treats them that way. If the server sent something else, the app fails on that line with a message that names both types, instead of somewhere far away.

JSON values map to Dart types like this: text in quotes is a String, a whole number is an int, a number with a point is a double, and true or false is a bool. Note that true has no quotes: it is a bool, not the text 'true'.

challenge icon

Challenge

Medium

Show more of the profile. In the builder, read each value with as: name and email as String, age as int, isPro as bool. Then, under the email, add:

  • 28 years old, built from age
  • Pro member when isPro is true, and Free plan when it is not

Try it yourself

import 'dart:convert';

import 'package:flutter/material.dart';

import 'api.dart';

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

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

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

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

  @override
  State<ProfileScreen> createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  late Future<Map<String, dynamic>> _user;

  @override
  void initState() {
    super.initState();
    _user = loadUser();
  }

  Future<Map<String, dynamic>> loadUser() async {
    final body = await fetch('/user');
    return jsonDecode(body);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: Center(
        child: FutureBuilder<Map<String, dynamic>>(
          future: _user,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Could not load: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              final user = snapshot.data!;
              return Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    user['name'],
                    style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 8),
                  Text(user['email'], style: const TextStyle(fontSize: 18)),
                ],
              );
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Data and the Network

Practice on your own: Online Flutter compiler