Zeyad Mohamed
Zeyad Mohamed

Reputation: 84

Null is not a subtype of type 'int'

I am using http and trying to display the data and an error shows to me in the screen instead of the data I defined all the variables with the null safety he should print the data inside the title not the error

this is the json class @link@ enter image description here

this is the code

// ignore_for_file: unused_local_variable, avoid_print
import 'dart:convert';

import 'package:appii/models/post.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

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

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  late Future<Post>
      postdata; // this one is for saving the data in variable that i can use it anywhere

  //we did the init state to allow the compile to print the data
  @override
  void initState() {
    super.initState();
    postdata = getPostById();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Networking http lesson 1'),
      ),
      body: Center(
        child: FutureBuilder<Post>(
          future: postdata, // the data source
          // in the builder i am going to desigm the place where the data will be in and it take @1- Context 2- snapshot@
          builder: (context, snapshot) {
            // this one is to see if there is data or eror
            if (snapshot.hasData) {
              return Text(snapshot.data!.title);
            } else if (snapshot.hasError) {
              return Text('error is ${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }

  // this is the fuction that by it iam requesting to use the http package @http.@ this is an object from the package i called containes all the methods inside this package
  Future<Post> getPostById() async {
    http.Response futurepost = await http.get(
      Uri.parse(
          'https://jsonplaceholder.typicode.com/posts/1'), // here in http.get or http.post first yu have to put ur url in the shape of @Uri.parse@ To improve compile-time type safety
    );
    //this method @if@ like .then but here i making sure that tha api and the link is working
    if (futurepost.statusCode == 200) {
      // success
      print(futurepost.body);
      return Post.fromjson(json.decode(futurepost
          .body)); // in thie retuen iam taking the data and convert it form data with double qoutations to json
    } else {
      throw Exception(
          'can not load data'); // here iam catching the error if there is one
    }
  }
}

here is the json i did with the constructor and named constructor


// this is the custom Response object
class Post {
  late int userId;
  late int id;
  late String title;
  late String body;
  // normal Constructor
  Post({
    required this.userId,
    required this.id,
    required this.title,
    required this.body,
  });
  //named Constructor
  //factory is meaning that i do not want to create a new object every time but to use escesting one
  factory Post.fromjson(Map<String, dynamic> jason) {
    return Post(
      id: jason['id'],
      userId: jason['UserId'],
      title: jason['title'],
      body: jason['body'],
    );
  }
}

Upvotes: 0

Views: 63

Answers (1)

esentis
esentis

Reputation: 4666

I like how you call json as jason makes it more personal, moreover the issue is most probably due to a typo here userId: jason['UserId'] because your screenshot shows it as userId: jason['userId'].

Upvotes: 2

Related Questions