I want to save AppInfo information from API into SharedPreferences. I have source code and result JSON like this :
APP_INFO_API.dart:
Future<List> getAppInfo() async {
try {
final response = await http.get(
"${appConfig.baseApiUrl}/${appConfig.appInfoController}/getLogoClient");
final Map<String, dynamic> responseJson = json.decode(response.body);
if (responseJson["status"] == "ok") {
List appInfoList = responseJson["data"];
print('List Dynamic From API : $appInfoList ');
return appInfoList;
} else {
throw CustomError(responseJson["message"]);
}
} catch (e) {
return Future.error(e.toString());
}
}
Result JSON
List Dynamic From API : [{kodeInfo: 1, namaInfo: Integrasi Operasional Outlet, keteranganInfo: Burger Klenger ERPOS Version 1.2, fileInfo: img-1.png, logoInfo: logo-1.png, loginBackgroundInfo: bfront-1.png, loginLeftInfo: bleft-1.png, loginSupportInfo: bsupport-1.png, createBy: , createTime: 0000-00-00 00:00:00, updateBy: hambaallah, updateTime: 2020-02-09 06:32:57}]
I already read the documentation about type data that can be store in SharedPreferences, and I found can be store as List[String]. The problem is return of appInfoList above is List[dynamic], It's possible convert from List[dynamic] to List[String], so i can add it to SharedPreferences ?
My Experiment
I follow This Link and try to implement it.
I create GlobalProvider To Store Value From API.
class GlobalProvider extends ChangeNotifier {
static const _APP_INFO_LIST123 = "appInfoList123";
GlobalProvider() {
syncDataWithProvider();
}
List<AppInfoModel> appInfoList123 = [];
Future updateSharedPreferencesAppInfo123(List<dynamic> value) async {
List<String> myAppInfoList123 = value.map((e) => json.encode(e)).toList();
SharedPreferences prefs = await SharedPreferences.getInstance();
final result =
await prefs.setStringList(_APP_INFO_LIST123, myAppInfoList123);
print('result from updateSP $result');
print('Myappinfolist123 : $myAppInfoList123');
}
Future syncDataWithProvider() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var result = prefs.getStringList(_APP_INFO_LIST123);
print('The Result is $result');
if (result != null) {
appInfoList123 = result
.map<AppInfoModel>((e) => AppInfoModel.fromJson(json.decode(e)))
.toList();
}
print('Hore $appInfoList123');
notifyListeners();
}
}
Then, when I access it like this :
SplashScreen.dart
class _SplashScreenState extends State<SplashScreen> {
GlobalProvider globalProvider;
@override
void didChangeDependencies() {
super.didChangeDependencies();
globalProvider = Provider.of<GlobalProvider>(context);
testing(globalProvider);
}
testing(GlobalProvider gp) async {
final appInfoList = appInfoApi.getAppInfo();
final result = await appInfoList;
print('Hello List Dynamic From didChangeDependecies : $result');
return await gp.updateSharedPreferencesAppInfo123(result);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text(globalProvider.appInfoList123[0].fileInfo)), <!!! IN HERE
);
}
}
But i got this error
Error

I/flutter (26131): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (26131): The following RangeError was thrown building SplashScreen(dirty, dependencies:
I/flutter (26131): [_DefaultInheritedProviderScope<GlobalProvider>], state: _SplashScreenState#a10e3):
I/flutter (26131): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter (26131):
I/flutter (26131): The relevant error-causing widget was:
I/flutter (26131): SplashScreen
lib\main.dart:42
I/flutter (26131):
I/flutter (26131): When the exception was thrown, this was the stack:
I/flutter (26131): #0 List.[] (dart:core-patch/growable_array.dart:146:60)
I/flutter (26131): #1 _SplashScreenState.build
package:klenger_burger_app/screens/splash_screen.dart:88
I/flutter (26131): #2 StatefulElement.build
package:flutter/…/widgets/framework.dart:4590
I/flutter (26131): #3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4478
I/flutter (26131): #4 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4646
I/flutter (26131): #5 Element.rebuild
package:flutter/…/widgets/framework.dart:4202
I/flutter (26131): #6 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4461
I/flutter (26131): #7 StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:4637
I/flutter (26131): #8 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4456
I/flutter (26131): ... Normal element mounting (115 frames)
I/flutter (26131): #123 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3430
I/flutter (26131): #124 MultiChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5857
I/flutter (26131): ... Normal element mounting (253 frames)
I/flutter (26131): #377 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3430
I/flutter (26131): #378 Element.updateChild
package:flutter/…/widgets/framework.dart:3198
I/flutter (26131): #379 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4498
I/flutter (26131): #380 _InheritedProviderScopeMixin.performRebuild
package:provider/src/inherited_provider.dart:220
I/flutter (26131): #381 Element.rebuild
package:flutter/…/widgets/framework.dart:4202
I/flutter (26131): #382 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4461
I/flutter (26131): #383 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4456
I/flutter (26131): ... Normal element mounting (7 frames)
I/flutter (26131): #390 SingleChildWidgetElementMixin.mount
package:nested/nested.dart:223
I/flutter (26131): ... Normal element mounting (7 frames)
I/flutter (26131): #397 _NestedHookElement.mount
package:nested/nested.dart:188
I/flutter (26131): ... Normal element mounting (7 frames)
I/flutter (26131): #404 SingleChildWidgetElementMixin.mount
package:nested/nested.dart:223
I/flutter (26131): #405 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3430
I/flutter (26131): #406 Element.updateChild
package:flutter/…/widgets/framework.dart:3198
I/flutter (26131): #407 RenderObjectToWidgetElement._rebuild
package:flutter/…/widgets/binding.dart:1142
I/flutter (26131): #408 RenderObjectToWidgetElement.mount
package:flutter/…/widgets/binding.dart:1113
I/flutter (26131): #409 RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure>
package:flutter/…/widgets/binding.dart:1055
I/flutter (26131): #410 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2591
I/flutter (26131): #411 RenderObjectToWidgetAdapter.attachToRenderTree
package:flutter/…/widgets/binding.dart:1054
I/flutter (26131): #412 WidgetsBinding.attachRootWidget
package:flutter/…/widgets/binding.dart:935
I/flutter (26131): #413 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure>
package:flutter/…/widgets/binding.dart:917
I/flutter (26131): (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
I/flutter (26131):
I/flutter (26131): ════════════════════════════════════════════════════════════════════════════════════════════════════
Any recommendation how can i adding List[dynamic] into SharedPreferences ?
If you need My Model
class AppInfoModel {
String kodeInfo;
String namaInfo;
String keteranganInfo;
String fileInfo;
String logoInfo;
String loginBackgroundInfo;
String loginLeftInfo;
String loginSupportInfo;
String createBy;
String createTime;
String updateBy;
DateTime updateTime;
AppInfoModel({
this.kodeInfo,
this.namaInfo,
this.keteranganInfo,
this.fileInfo,
this.logoInfo,
this.loginBackgroundInfo,
this.loginLeftInfo,
this.loginSupportInfo,
this.createBy,
this.createTime,
this.updateBy,
this.updateTime,
});
factory AppInfoModel.fromJson(Map<String, dynamic> json) => AppInfoModel(
kodeInfo: json["kodeInfo"] == null ? '' : json["kodeInfo"],
namaInfo: json["namaInfo"] == null ? '' : json["namaInfo"],
keteranganInfo:
json["keteranganInfo"] == null ? '' : json["keteranganInfo"],
fileInfo: json["fileInfo"] == null ? '' : json["fileInfo"],
logoInfo: json["logoInfo"] == null ? '' : json["logoInfo"],
loginBackgroundInfo: json["loginBackgroundInfo"] == null
? ''
: json["loginBackgroundInfo"],
loginLeftInfo:
json["loginLeftInfo"] == null ? '' : json["loginLeftInfo"],
loginSupportInfo:
json["loginSupportInfo"] == null ? '' : json["loginSupportInfo"],
createBy: json["createBy"] == null ? '' : json["createBy"],
createTime: json["createTime"] == null ? '' : json["createTime"],
updateBy: json["updateBy"] == null ? '' : json["updateBy"],
updateTime: DateTime.parse(json["updateTime"]) == null
? ''
: DateTime.parse(json["updateTime"]),
);
Map toJson() => {
'kodeInfo': this.kodeInfo,
'namaInfo': this.namaInfo,
'keteranganInfo': this.keteranganInfo,
'fileInfo': this.fileInfo,
'logoInfo': this.logoInfo,
'loginBackgroundInfo': this.loginBackgroundInfo,
'loginLeftInfo': this.loginLeftInfo,
'loginSupportInfo': this.loginSupportInfo,
'createBy': this.createBy,
'createTime': this.createTime,
'updateBy': this.updateBy,
'updateTime': this.updateTime,
};
}
final appInfoModel = AppInfoModel();
json.encodeing on writing andjson.deocdeing when reading?