skip to Main Content

I’m trying to get currency conversion data from an API ("https://api.exchangerate.host/latest").

The above error in the title is shown on the screen as a text.

I’m trying to get this message as the output.

"msg":"If you or your company use this project or like what we doing, please consider backing us so we can continue maintaining and evolving this project."

Later the individual currency rates.

import 'dart:async';
import 'dart:convert';

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

Future<Album> fetchAlbum() async {
  final response = await http.get(Uri.parse('https://api.exchangerate.host/latest'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class Album {
  final String msg;

  Album({
    required this.msg,
  });

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

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

  @override
  _CurrencyPageState createState() => _CurrencyPageState();
}

class _CurrencyPageState extends State<CurrencyPage> {
  late Future<Album> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Album>(
            future: futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data!.msg);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }

              // By default, show a loading spinner.
              return const CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

Any help would be appreciated!

2

Answers


  1. msg key is inside motd object in response. Therefore replace fetchAlbum with this:

    Future<Album> fetchAlbum() async {
      final response = await http.get(Uri.parse('https://api.exchangerate.host/latest'));
    
      if (response.statusCode == 200) {
        // If the server did return a 200 OK response,
        // then parse the JSON.
        var body = jsonDecode(response.body);
        
        return Album.fromJson(body["motd"]);
      } else {
        // If the server did not return a 200 OK response,
        // then throw an exception.
        throw Exception('Failed to load album');
      }
    }
    
    Login or Signup to reply.
  2. you are using the model incorrectly.
    change return Album.fromJson(jsonDecode(response.body)); to return jsonDecode(response.body); and get response data like snapshot.data!['motd']

    code:

    Future<dynamic> fetchAlbum() async {
      final response = await http.get(Uri.parse('https://api.exchangerate.host/latest'));
    
      if (response.statusCode == 200) {
    
        // If the server did return a 200 OK response,
        // then parse the JSON.
        print(jsonDecode(response.body));
        return jsonDecode(response.body);
      } else {
        // If the server did not return a 200 OK response,
        // then throw an exception.
        throw Exception('Failed to load album');
      }
    }
    
    class Album {
      final String msg;
    
      Album({
        required this.msg,
      });
    
      factory Album.fromJson(Map<String, dynamic> json) {
        return Album(
          msg: json['msg'],
        );
      }
    }
    
    class CurrencyPage extends StatefulWidget {
      const CurrencyPage({Key? key}) : super(key: key);
    
      @override
      _CurrencyPageState createState() => _CurrencyPageState();
    }
    
    class _CurrencyPageState extends State<CurrencyPage> {
      late dynamic futureAlbum;
    
      @override
      void initState() {
        super.initState();
        futureAlbum = fetchAlbum();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: const Text('Fetch Data Example'),
            ),
            body: Center(
              child: FutureBuilder<dynamic>(
                future: futureAlbum,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return Text(snapshot.data!['motd']['msg']);
                  } else if (snapshot.hasError) {
                    return Text('${snapshot.error}');
                  }
    
                  // By default, show a loading spinner.
                  return const CircularProgressIndicator();
                },
              ),
            ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search