Home > Back-end >  Why does it say that it expected a value of type int if what I want to obtain is of type string?
Why does it say that it expected a value of type int if what I want to obtain is of type string?

Time:08-08

It is confusing to me because the url shows that it is a string, since it is obviously an image. here it tells me that it expects a value of type int I don't understand what value is the integer. if the image expects a url of type string

enter image description here

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

import '../models/catdata.dart';

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

  @override
  State<Apicat> createState() => _ApicatState();
}

class _ApicatState extends State<Apicat> {
  Future<List<CatData>> fetchCatdata() async {
    final response = await http.get(Uri.parse(
        'https://api.thecatapi.com/v1/images/search?limit=22&breed_ids=beng&api_key=f9891ce2-f1db-425d-bed0-0dcc1eb8be97'));

    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      final data = jsonDecode(response.body);
      // este es un array de Strings
      final list = data['url'] as List;
      //final list2 = data['origin'] as List;

      // pasa la data a objetos catData, recorriendo los strings y transformandolos a objeto
      //final listCatData = list.map((item) => CatData(imagen: item)).toList();
      return list.map((e) => CatData(imagen: e)).toList();
      //return list.map((e) => CatData(imagen: e, origen: list2[0])).toList();
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load album');
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<CatData>>(
      future: fetchCatdata(),
      builder: (BuildContext context, AsyncSnapshot<List<CatData>> snapshot) {
        if (snapshot.hasData) {
          //crea dos listas de catData, una para la imagen y otra para la descripcion
          final list = snapshot.data!;

          //final list2 = snapshot.data!;
          return ListView.builder(
            itemCount: list.length,
            itemBuilder: (BuildContext context, int index) {
              return Image.network(list[index].imagen);
            },
          );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }
        // By default, show a loading spinner.
        return CircularProgressIndicator();
      },
    );
  }
}

and here the url https://api.thecatapi.com/v1/images/search?limit=22&breed_ids=beng&api_key=f9891ce2-f1db-425d-bed0-0dcc1eb8be97

here the class model

class CatData{
        final String imagen;

  CatData({required this.imagen});



  factory CatData.fromJson(Map<String, dynamic> json) {
    return CatData(
      imagen: json['url'],
              );
  }
}

            

CodePudding user response:

The issue was using

final list = data['url'] as List;. The response itself a list.

and providing list. To perse it do it like

  if (response.statusCode == 200) {
      final data = jsonDecode(response.body) as List;
      return data.map((e) => CatData.fromMap(e)).toList();
    } 

Also I've modify the model class a little

class CatData {
  final String imagen;
  CatData({
    required this.imagen,
  });

  Map<String, dynamic> toMap() {
    final result = <String, dynamic>{};

    result.addAll({'imagen': imagen});

    return result;
  }

  factory CatData.fromMap(Map<String, dynamic> map) {
    return CatData(
      imagen: map['imagen'] ?? '',
    );
  }

  String toJson() => json.encode(toMap());

  factory CatData.fromJson(String source) =>
      CatData.fromMap(json.decode(source));
}

This will give a little push on parsing


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

  @override
  State<Apicat> createState() => _ApicatState();
}

class _ApicatState extends State<Apicat> {
  Future<List<CatData>?> fetchCatdata() async {
    final response = await http.get(
      Uri.parse(
          'https://api.thecatapi.com/v1/images/search?limit=2&breed_ids=beng&api_key=f9891ce2-f1db-425d-bed0-0dcc1eb8be97'),
    );
    if (response.statusCode == 200) {
      final data = jsonDecode(response.body) as List;
      return data.map((e) => CatData.fromMap(e)).toList();
    } else {
      throw Exception('Failed to load album');
    }
  }

  late final future = fetchCatdata();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<List<CatData>?>(
        future: future,
        builder: (BuildContext context, snapshot) {
          if (snapshot.hasData) {
            final list = snapshot.data!;
            print(list);

            return ListView.builder(
              itemCount: list.length,
              itemBuilder: (BuildContext context, int index) {
                return Image.network(list[index].imagen);
              },
            );
          } else if (snapshot.hasError) {
            return Text("Error  ${snapshot.stackTrace}");
          }
          // By default, show a loading spinner.
          return CircularProgressIndicator();
        },
      ),
    );
  }
}

CodePudding user response:

Let's see. Your problem is the api returns a list of data and you want to take the url of all the children on the list, so to do that you need to convert the json response to a list, then you can take the url by adding these three lines.

  final data = jsonDecode(response.body) as List<dynamic>;
  final List<CatData> list = data.map((e) => CatData(imagen: e['url'])).toList();
  return list;
  • Related