Can't get the JSON data from openweathermap API to my flutter app

Whereas it totally works when I do it with curl like this:

curl 'https://api.openweathermap.org/data/2.5/weather?lat={41.01}&lon={28.97}&appid={my_secret_api_key}'

Openweathermap is free you can try it yourself, remember to verify email otherwise it won’t work.
And this is my app in flutter. Ignore the album classes, I didn’t change them according to the data sent back yet because I need to fix this issue first, json doesn’t come at all.

Just check the response.body variable, it gives 401 error. This is problematic. Turning json into the flutter data is not a big problem for me:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
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.openweathermap.org/data/2.5/weather?lat={41.01}&lon={28.97}&appid=${HttpHeaders.authorizationHeader}'),
    // Send authorization headers to the backend.
    headers: {
      HttpHeaders.authorizationHeader: '666319c58bc57caab32599c61b82c50e',
    },
  );
  print('response body: ${response.body}');
  final responseJson = jsonDecode(response.body);

  return Album.fromJson(responseJson);
}


void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  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!.title);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }

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

//IGNORE THESE PLEASE, NOT IMPORTANT YET. SO I MOVED THEM HERE.
class Album {
  final int userId;
  final int id;
  final String title;

  const Album({
    required this.userId,
    required this.id,
    required this.title,
  });

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

>Solution :

Like I said in my comment, remove the header of your request and use the interpolation without it.

String myKey = 'myKey';
Uri.parse(
    'https://api.openweathermap.org/data/2.5/weather?lat={41.01}&lon={28.97}&appid=$myKey'),
)

Leave a Reply