elios_cama
elios_cama

Reputation: 217

Error with the snapshot while fetching data from api Flutter

I'm struggling trying to code a Flutter app using the newsApi. I tried every mean to fetch the data from the internet but at the end, the snapshot has an error that i can't figure out how to fix.

Here is the error:

I/flutter ( 8549): NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' 
has no instance method 'cast' with matching arguments.
I/flutter ( 8549): Receiver: _LinkedHashMap len:3
I/flutter ( 8549): Tried calling: cast<Map<String, dynamic>>()
I/flutter ( 8549): Found: cast<Y0, Y1>() => Map<Y0, Y1>

Here's my model of news :

class NewsModel {
//Source  source;
String title;
String urlToImage;
String author;
String description;
String content;
String url;

NewsModel(
  {
  //required this.source,
  required this.title,
  required this.urlToImage,
  required this.author,
  required this.description,
  required this.content,
  required this.url});
  factory NewsModel.fromMap(Map<String, dynamic> json) => NewsModel(
  title: json['title'],
  urlToImage: json['urlToImage'],
  author: json['auhtor'],
  description: json['description'],
  content: json['content'],
  url: json['url']);
  }

Here's my main file:

Future<List<NewsModel>> fetchPost() async {
final response = await http.get(Uri.parse(
  'https://newsapi.org/v2/everything?q=tesla&from=2022-01- 
23&sortBy=publishedAt&apiKey=~~~~~~~~~~~~'));

if (response.statusCode == 200) {

final parsed = json.decode(response.body).cast<Map<String, dynamic>>();

return parsed.map<NewsModel>((json) => NewsModel.fromMap(json)).toList();
} else {
throw Exception('Failed to load album');
 }
 }

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

 @override
 State<HomePage> createState() => _HomePageState();
 }

 class _HomePageState extends State<HomePage> {
late Future<List<NewsModel>> futureNews;

@override
void initState() {
super.initState();
futureNews = fetchPost();
}

    @override
  Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;

return Scaffold(
  backgroundColor: Colors.black,
  appBar: AppBar(
    centerTitle: true,
    title: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Appsolute'),
        Text(
          'News',
          style: TextStyle(color: Colors.blueAccent),
        )
      ],
    ),
    backgroundColor: Colors.black,
  ),
  body: Column(
    children: [
      Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: Row(
          children: [
            Expanded(
              child: TextField(
                cursorColor: Colors.black,
                decoration: InputDecoration(
                    hintText: 'Search titles',
                    filled: true,
                    fillColor: Colors.white,
                    enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.white),
                      borderRadius: BorderRadius.circular(15),
                    ),
                    border: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.white),
                      borderRadius: BorderRadius.circular(15),
                    ),
                    focusedBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.white),
                      borderRadius: BorderRadius.circular(15),
                    )),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 8),
              child: Icon(
                Icons.star_border_outlined,
                color: Colors.white,
              ),
            )
          ],
        ),
      ),
      FutureBuilder(
          future: futureNews,
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Text('none');
              case ConnectionState.waiting:
                return Center(child: CircularProgressIndicator());
              case ConnectionState.active:
                return Text('');
              case ConnectionState.done:
                if (snapshot.hasError) {
                  print(snapshot.error);
                  return Text(
                    '${snapshot.error}',
                    
                    style: TextStyle(color: Colors.red),
                  );

                } else {}
                return Container(
                  color: Colors.blue,
                  child: Text("successss"),
                );
            }
          })
        ],
    ),
  );
  }
  }

Can you please tell me where the error is and how to fetch correctly the data? Thanks guys!

Upvotes: 3

Views: 458

Answers (1)

Roman Jaquez
Roman Jaquez

Reputation: 2779

You're decoding the response.body but then you're casting as a Map<String, dynamic>, which if I'm not mistaken, your response.body is a collection of Map<String, dynamic>, so try casting it into a List<Map<String, dynamic>, so you can do this instead:

final parsed = json.decode(response.body) as List<Map<String, dynamic>;
return parsed.map((json) => NewsModel.fromMap(json)).toList();

Try and let me know if that works.

Upvotes: 1

Related Questions