Unhandled Exception: type 'String' is not a subtype of type 'List<dynamic>

Issue

I earlier created an API using AWS Lambda and API gateway which fetches the data from my DynamoDB table.

Here’s my lambda function


const AWS = require("aws-sdk");
const documentClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async event => {
  const params = {
    TableName: "//tableName" 
  };
  try {
    // Utilising the scan method to get all items in the table
    const data = await documentClient.scan(params).promise();
    const response = {
      statusCode: 200,
      body: JSON.stringify(data.Items)
    };
    return response;
  } catch (e) {
    return {
      statusCode: 500
    };
  }
};

Here’s the sample response from the API.

{"statusCode":200,"body":"[{\"product\":\"clear\",\"__typename\":\"ProductModel\",\"size\":\"small\",\"_lastChangedAt\":1625829002606,\"_version\":1,\"company\":\"add\",\"updatedAt\":\"2021-07-09T11:10:02.578Z\",\"category\":\"Pot\",\"createdAt\":\"2021-07-09T11:10:02.578Z\",\"price\":\"69\",\"description\":\"this doesn't even make sense\",\"id\":\"f4acb29c-f8f3-4765-abf6-aef0002a837c\"},\{\"product\":\"product\",\"__typename\":\"ProductModel\",\"size\":\"1\",\"_lastChangedAt\":1625988107746,\"_version\":1,\"company\":\"company\",\"updatedAt\":\"2021-07-11T07:21:47.704Z\",\"category\":\"Climbers\",\"createdAt\":\"2021-07-11T07:21:47.704Z\",\"price\":\"221\",\"description\":\"description\",\"id\":\"0a51d3c3-4df3-4549-abaa-f8b88e8ac407\"}]"}
{"mode":"full","isActive":false}

Now when I go through the usual steps of decoding the body of the response. I get this error as
Unhandled Exception: type ‘String’ is not a subtype of type ‘List.
Here’s how I am doing it

void getProductData() async {
  List list ;
  var response = await http.get(Uri.parse('//api-endpoint'));
  Map<String,dynamic> map  = json.decode(response.body);
  list = map["body"];
}

Decoded JSON Response

{statusCode: 200, body: [{"product":"clear","__typename":"ProductModel","size":"small","_lastChangedAt":1625829002606,"_version":1,"company":"add","updatedAt":"2021-07-09T11:10:02.578Z","category":"Pot","createdAt":"2021-07-09T11:10:02.578Z","price":"69","description":"this doesn't even make sense","id":"f4acb29c-f8f3-4765-abf6-aef0002a837c"},{"product":"product","__typename":"ProductModel","size":"1","_lastChangedAt":1625988107746,"_version":1,"company":"company","updatedAt":"2021-07-11T07:21:47.704Z","category":"Climbers","createdAt":"2021-07-11T07:21:47.704Z","price":"221","description":"description","id":"0a51d3c3-4df3-4549-abaa-f8b88e8ac407"}]
}

Solution

Can you try the below lines?

— The first solution looks correct, but I’ve improved it a bit. Let’s proceed this way.

void getProductData() async {
  List<Map<String,dynamic>> list;
  final response = await http.get(Uri.parse('//api-endpoint'));
  Map<String,dynamic> map  = json.decode(response.body);
  final body = map['body'];
  
  if(body is List){
  list = List.from(map["body"] as List<Map<String,dynamic>>);
  }else {
    print('Body is\'nt List');
  }
}

Answered By – Salih Can

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *