Null return from flutter http post request

Viewed 51

I am trying to authenticate a user in my flutter application but I keep getting a null responses. Below is the login function.

   Future<ApiResponse> login(String email, String password) async {
    ApiResponse apiResponse = ApiResponse();

    try {
          // This response variable returns null;
      final response = await http.post(
        Uri.parse(projectApis.loginUrl),
        body: json.encode({"email": email, "password": password}),
        headers: projectApis.headers,
      );

      switch (response.statusCode) {
        case 200:
          apiResponse.data = User.fromJson(json.decode(response.body));
          break;
        case 422:
          final error = json.decode(response.body)['errors'];
          apiResponse.message = error[error.keys.elementAt(0)][0];
          break;
        case 401:
          apiResponse.message = json.decode(response.body)['message'];
          break;
        default:
          apiResponse.message = projectApis.errorMessage;
          break;
      }
    } catch (e) {
      apiResponse.message = projectApis.errorMessageServer;
    }

    return apiResponse;
  }

This is the ApiResponse

class ApiResponse {
  Object? data;
  String message = '';
}

This is the User model

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

  int id;
  String name;
  String email;
  String token;

  factory User.fromJson(Map<String, dynamic> json) => User(
        id: json["id"],
        name: json["name"],
        email: json["email"],
        token: json["token"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "email": email,
        "token": token,
      };

  @override
  String toString() {
    return 'User{ name: $name, email: $email, token: $token}';
  }
}

This is the login method

loginUser() async {
    ApiResponse response = await authController.login(
      _emailController.text,
      _passwordController.text,
    );

    if (response.message == "success") {
      saveAndRedirectToHome(response.data as User);
    } else {
      setState(() {
        isLoading = false;
      });
      Get.snackbar(
        "",
        "${response.message}",
        snackPosition: SnackPosition.BOTTOM,
        colorText: Colors.white,
        backgroundColor: Colors.red,
      );
    }
  }

  void saveAndRedirectToHome(User user) async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    await pref.setString('token', user.token);
    await pref.setInt('userId', user.id);
    Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => BottomNavigation()),
        (route) => false);
  }

Login response from API

{
    "token": "30|CEqsqkpyJvZCLg88jh3fPTTxkJB4lGhForIKtcth",
    "email": "testi@gmail.com",
    "name": "Kennedy Owusu"
}
1 Answers

You forgot to set the message in your switch case when it is success:

case 200:
  apiResponse.data = User.fromJson(json.decode(response.body));
  apiResponse.message = 'success'; //add this line here
  break;

And your response doesn't include id, so convert it to nullable:

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

  int? id;
  String name;
  String email;
  String token;

  factory User.fromJson(Map<String, dynamic> json) => User(
        id: json["id"],
        name: json["name"],
        email: json["email"],
        token: json["token"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "email": email,
        "token": token,
      };

  @override
  String toString() {
    return 'User{ name: $name, email: $email, token: $token}';
  }
}
Related