I'm learning flutter by making a simple photo gallery from unsplash service and trying to fetch a list of photos from https://api.unsplash.com/photos.
I'm getting the runtime error:
type 'Future<dynamic>' is not a subtype of type 'FutureOr<List<Photo>>'
Though if I print a list instead of returning it I get a list of instances of Photo in console. What's wrong with my code and how to do it right?
My photo model looks like this:
class Photo {
final String id;
final String title;
final String username;
final String url;
Photo({this.id, this.title, this.username, this.url});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
id: json['id'],
title: json['alt_description'],
username: json['user']['name'],
url: json['urls']['raw']);
}
}
My api data source:
import 'package:http/http.dart' as http;
import 'dart:convert';
class UnsplashApi {
final String _clientId =
"84y4hgje4ac868c2646c0eddjhfedihdhff612b04c264f3374c97fff98ed253dc9";
Future<String> _fetch(String url) async {
try {
url = buildUrl(url);
var response = await http.get(url);
if (response.statusCode == 200) {
return response.body;
}
} catch (e) {
print(e);
}
}
Future<dynamic> fetchDataByUrl(String url) async {
var data = await _fetch(url);
try {
return json.decode(data);
} catch (e) {
print('Bad content, could not decode JSON');
}
}
String buildUrl(url) {
return url.contains('?')
? url + '&client_id=$_clientId'
: url + '?client_id=$_clientId';
}
}
My repository contract (interface):
import 'package:unsplash/domain/models/photo.dart';
abstract class PhotosRepository {
Future<List<Photo>> getPhotosList();
}
My Unsplash Photos repository:
import 'package:unsplash/domain/models/photo.dart';
import 'package:unsplash/domain/repositories/photos_repository.dart';
import 'package:unsplash/infrastructure/data_sources/unsplash_api.dart';
class UnsplashPhotosRepository implements PhotosRepository {
final UnsplashApi _api;
final String _url = 'https://api.unsplash.com/photos';
UnsplashPhotosRepository(this._api);
@override
Future<List<Photo>> getPhotosList() async {
var result = _api.fetchDataByUrl(_url).then((data) {
var list = data?.map((el) => Photo.fromJson(el)).toList();
return list;
});
return result;
}
}
And My test:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:unsplash/infrastructure/data_sources/unsplash_api.dart';
import 'package:unsplash/infrastructure/repositories/unsplash_photos_repository.dart';
void main() {
group('Unsplash api', () {
test('should get search results', () async {
final api = UnsplashApi();
var result = await UnsplashPhotosRepository(api).getPhotosList();
print(result.runtimeType);
expect(result.isEmpty, false);
});
});
}