Почему функция возвращает пустой список во Flutter
Итак, вот код. Ошибка заключается в том, что вызов функции loadSounds извне класса возвращает пустой список. Но когда loadSounds вызывается из loadcategories, он работает нормально и возвращает список, содержащий экземпляры Sound. Даже при выводе переменной звуков в функцию loadSounds печатается пустой список.
class AudioRepository {
List<Category> categories = <Category>[];
List<Sound> sounds = <Sound>[];
Future<String> _loadCategoriesAsset() async =>
await rootBundle.loadString(Assets.soundsJson);
Future<List<Category>> loadCategories() async {
if (categories.isNotEmpty) {
return categories;
}
String jsonString = await _loadCategoriesAsset();
categories.clear();
categories.addAll(categoryFromJson(jsonString));
categories.map((c) => sounds.addAll(c.sounds)).toList();
loadSounds('1');
return categories;
}
Future<List<Sound>> loadSounds(String categoryId) async {
print(sounds);
return sounds
.where((sound) => sound.id.substring(0, 1) == categoryId)
.toList();
}
}
Вывод при вызове из loadCategories выглядит следующим образом:
[Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound']
Я получаю доступ к нему вне класса следующим образом:
final _sounds = await repository.loadSounds(event.categoryId);
Вывод при вызове извне или печати из функции loadSounds выглядит следующим образом:
[]
Так в чем тут проблема. Я не могу понять, почему функция loadSounds работает при вызове из loadCategories внутри класса и никак иначе.
Вот класс звука:
import 'package:meta/meta.dart';
class Sound {
String id;
String title;
Sound({
@required this.id,
@required this.title,
});
Sound copyWith({
String id,
String title,
}) =>
Sound(
id: id ?? this.id,
title: title ?? this.title,
);
factory Sound.fromJson(Map<String, dynamic> json) => Sound(
id: json["id"],
title: json["title"]
);
Map<String, dynamic> toJson() =>
{"id": id, "title": title};
}
Sounds.json:
[
{
"id": "1",
"title": "City",
"sounds": [
{
"id": "101",
"title": "Airplane"
},
{
"id": "102",
"title": "Car"
},
]
},
{
"id": "2",
"title": "Meditation",
"sounds": [
{
"id": "201",
"title": "Bells"
},
{
"id": "202",
"title": "Bowl"
}
]
},
]
3 ответа
Если ты не позвонишь
repository.loadCategories()
перед звонком
loadSounds()
, у вас не будет ничего в вашей переменной звуков, поскольку вы назначаете значения только в своей
loadCateogries()
функция.
Является ли ваша переменная репозитория синглтоном и вызывали ли вы для нее loadCategories?
Кроме того, я бы не стал писать вот так:
categories.map((c) => sounds.addAll(c.sounds)).toList();
В
toList()
метод не очень полезен, и функцию карты следует использовать больше для преобразования чего-либо (например, сопоставление String с Int).
Я хотел бы использовать :
categories.forEach((c)=> sounds.addAll(c.sounds));
используйте provider и ChangeNotifier - лучший способ. ваш код будет таким
class AudioRepository extends ChangeNotifier {
List<Category> categories = <Category>[];
List<Sound> sounds = <Sound>[];
Future<String> _loadCategoriesAsset() async =>
await rootBundle.loadString(Assets.soundsJson);
Future<List<Category>> loadCategories() async {
if (categories.isNotEmpty) {
return categories;
}
String jsonString = await _loadCategoriesAsset();
categories.clear();
categories.addAll(categoryFromJson(jsonString));
categories.map((c) => sounds.addAll(c.sounds)).toList();
//notify listeners
notifyListeners();
////
loadSounds('1');
return categories;
}
Future<List<Sound>> loadSounds(String categoryId) async {
print(sounds);
return sounds
.where((sound) => sound.id.substring(0, 1) == categoryId)
.toList();
}
}
для извлечения данных извне следует поместить следующий код в
Build()
метод.
final _arp = Provider.of<AudioRepository>(context, listen: true);
print(_arp._sounds);
Это может быть ошибка в предложении where. Потому что условие неправильное. попробуй это:
return sounds
.where((sound) => sound.id[0] == categoryId)
.toList();