Search code examples
flutterauthenticationdio

Flutter 'String' is not a subtype of type 'Map<dynamic, dynamic>'


i am a beginner in flutter dev and i have a project that need to consume api for login purpose, but i am facing an error like this : type 'String' is not a subtype of type 'Map<dynamic, dynamic>'

can anyone hlep me to solve the problem above ?

here is my code:

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

class AuthService {
  static String? token;
  Future<bool> login({
    required String email,
    required String password,
  }) async {
    try {
      var response = await Dio().post(
        "http://my-api/index/login",
        options: Options(
          headers: {
            "Content-Type": "application/json",
          },
        ),
        data: {
          "email": email,
          "password": password,
        },
      );
      if (response.statusCode == 200) {
        Map obj = response.data;
        token = obj["data"]["token"];
        return true;
      } else {
        throw Exception('Failed to login');
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 401) {
        debugPrint('Error 400: ${e.response?.data}');
        throw Exception('Invalid email or password');
      } else {
        debugPrint('Error: ${e.toString()}');
        throw Exception('Failed to login');
      }
    }
  }
}

here is the structure of API :

{
  "status": 200,
  "message": "login success",
  "data": {
    "id": "622b",
    "email": "[email protected]",
    "roleId": "a11ea",
    "biodateId": "ba2",
    "createdAt": "2024",
    "updatedAt": "2024",
    "token": "token"  }
}

if error :

{
  "status": 401,
  "message": "Wrong Password"
}

Solution

  • Ensure that your response handling correctly reflects the structure of the JSON returned by your API.

    try {
          Response<dynamic> response = await dio.post(
            "http://my-api/index/login",
            options: Options(
              headers: {
                "Content-Type": "application/json",
              },
            ),
            data: {
              "email": email,
              "password": password,
            },
          );
    
          if (response.statusCode == 200) {
            if (response.data is Map<String, dynamic>) {
              Map<String, dynamic> responseData = response.data;
              Map<String, dynamic> data = responseData['data'];
              token = data['token'];
              return true;
            } else {
              throw Exception('Failed to parse data');
            }
          } else if (response.statusCode == 401) {
            throw Exception(response.data['message'] ?? 'Unauthorized');
          } else {
            throw Exception('Failed to login');
          }
        } on DioError catch (e) {
          if (e.response?.statusCode == 401) {
            print('Error 401: ${e.response?.data}');
            } else {
            print('Error: ${e.toString()}');
           }
        } catch (e) {
          print('Error: ${e.toString()}');
         }