How to put code with if in a separate method? - flutter

I'm using app navigation but I'm facing a problem that I can't put the if (initialLink != null)... code in a separate method so that I can then duplicate this method in different parts of the code, can you tell me how can I put this code in a separate method?
class AppRouter {
final BuildContext context;
AppRouter(this.context);
RouteMap buildRouteMap(PendingDynamicLinkData? initialLink) {
return RouteMap(
onUnknownRoute: (route) => const Redirect('/'),
routes: {
'/': (route) {
bool loggedIn =
Provider.of<AppState>(context, listen: false).isLoggedIn;
if (initialLink != null) {
String code;
final Uri deepLink = initialLink.link;
final String deeplinkString = deepLink.toString();
code = deepLink.queryParameters['code'] ?? 'No code';
var start = deeplinkString.lastIndexOf('/') + 1;
var end = deeplinkString.indexOf('?');
var extract = deeplinkString.substring(start, end);
if (extract == 'password-reset') {
return Redirect(
'/login/forgot-password',
queryParameters: {
'isSendEmail': 'true',
'code': code,
},
);
}
}
return const MaterialPage(
child: PhoneNumberPage(),
);
},
'/map': (route) {
bool loggedIn =
Provider.of<AppState>(context, listen: false).isLoggedIn;
if (loggedIn) {
return const Redirect('/home');
}
return const MaterialPage(
child: MapPage(
isUserAuth: false,
),
);
},
code to be placed in a separate function
if (initialLink != null) {
String code;
final Uri deepLink = initialLink.link;
final String deeplinkString = deepLink.toString();
code = deepLink.queryParameters['code'] ?? 'No code';
var start = deeplinkString.lastIndexOf('/') + 1;
var end = deeplinkString.indexOf('?');
var extract = deeplinkString.substring(start, end);
if (extract == 'password-reset') {
return Redirect(
'/login/forgot-password',
queryParameters: {
'isSendEmail': 'true',
'code': code,
},
);
}
}

try this.
void commonFunction(){
if (initialLink != null) {
String code;
final Uri deepLink = initialLink.link;
final String deeplinkString = deepLink.toString();
code = deepLink.queryParameters['code'] ?? 'No code';
var start = deeplinkString.lastIndexOf('/') + 1;
var end = deeplinkString.indexOf('?');
var extract = deeplinkString.substring(start, end);
if (extract == 'password-reset') {
return Redirect(
'/login/forgot-password',
queryParameters: {
'isSendEmail': 'true',
'code': code,
},
);
}
}
}
then call commonFunction() every where you need.

You use initialLink as the judgement of if..else condition. When you extract them you need to provide that parameter. Otherwise the code cannot find initialLink.
void commonFunction(PendingDynamicLinkData? initialLink){
if (initialLink != null) {
String code;
final Uri deepLink = initialLink.link;
final String deeplinkString = deepLink.toString();
code = deepLink.queryParameters['code'] ?? 'No code';
var start = deeplinkString.lastIndexOf('/') + 1;
var end = deeplinkString.indexOf('?');
var extract = deeplinkString.substring(start, end);
if (extract == 'password-reset') {
return Redirect(
'/login/forgot-password',
queryParameters: {
'isSendEmail': 'true',
'code': code,
},
);
}
}
}

Related

I am having problem with onSelect notifcation webengage via FCM notification while onBackground state(onPaused) for my Flutter Application

TL;DR
I am receiving notification on all state(foreground, background(on-Paused), terminated(on-Detached)) but it's redirecting me to the intended url only in(foreground and terminated state). Surprisingly, on receiving notification during foreground state, on-select notification works on-Background state(on-Paused) as well and I am redirected to my intended url. But the main problem is while recieving notification on-background state(on-Paused) without receiving notification on foreground at first, it just redirects me to where I was. Here is the code I am currently working on:
void afterInitFirebase() async {
NotificationSettings settings = await _firebaseMessaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
await _firebaseMessaging
.subscribeToTopic(topic)
.onError((error, stackTrace) => {print(error)});
await _firebaseMessaging.getToken().then((value) => {
Preference.setString(fcm_token, value),
});
await _firebaseMessaging.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
await _firebaseMessaging.getInitialMessage().then((RemoteMessage? message) {
if (message != null) {
// _handleIncomingLinks();
MyNotification().initMessaging(message, isPush: true);
}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
displayNotification(message);
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print("${message.from} =--> ON MESSAGE OPENED APP");
});
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
HttpOverrides.global = MyHttpOverrides();
try {
await Firebase.initializeApp().then((value) {
afterInitFirebase();
});
} catch (e) {
print(
"EXCEPTION ON MAIN:" + e.toString(),
);
}
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await fitNotification.getNotificationAppLaunchDetails();
final uri = await getInitialUri();
String initialRoute = splash_page;
String id = "0";
if (notificationAppLaunchDetails!.didNotificationLaunchApp) {
selectedNotificationPayload = notificationAppLaunchDetails.payload;
print("payload $selectedNotificationPayload");
var parts = selectedNotificationPayload?.split(SEPARATOR);
if (parts != null) {
if (parts[0] == "course" ||
parts[0].toLowerCase() == "coursedetails" ||
parts[0].toLowerCase() == "coursedetails") {
id = parts[1];
//course details page
initialRoute = course_details;
} else if (parts[0].toLowerCase() == "allcourse") {
initialRoute = all_course;
if (parts.length > 1) {
id = parts[1];
}
print("payload: $initialRoute $id");
} else if (parts[0].toLowerCase() == "allplan") {
if (parts.length > 1) {
id = parts[1];
}
initialRoute = "/allPlans";
} else if (parts[0].toLowerCase() == "web") {
id = parts[1];
initialRoute = web_page;
} else if (parts[0].toLowerCase() == "plan") {
id = parts[1];
initialRoute = plans_details_page;
} else if (parts[0].toLowerCase() == "quiz") {
initialRoute = web_page_entrance;
} else if (parts[0].toLowerCase() == "wishlist") {
initialRoute = route_wish_list;
} else if (parts[0].toLowerCase() == "carts") {
initialRoute = my_carts;
} else {
initialRoute = notification_page;
}
}
}
if (uri == null) {
} else {
String path = uri.toString();
if (path.toLowerCase().contains("coursedetails") ||
path.toLowerCase().contains("/home/course")) {
String idStr = uri.path.substring(uri.path.lastIndexOf('/') + 1);
id = idStr;
initialRoute = course_details;
}
}
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
displayNotification(message);
}
void displayNotification(RemoteMessage message) {
log(message.data.toString());
MyNotification().initMessaging(message);
}
This is my MyNotification class:
const String SEPARATOR = "|";
class MyNotification {
void initMessaging(RemoteMessage message, {isPush: true}) async {
var androidInit = AndroidInitializationSettings('ic_notification');
var iosInit = IOSInitializationSettings();
var initSetting =
InitializationSettings(android: androidInit, iOS: iosInit);
await fitNotification.initialize(initSetting,
onSelectNotification: onSelectNotification);
var rand = new Random();
int id = 1;
String? title = "";
String? body = "";
String? icon = "";
String? type = "";
String? itemId = "";
String link = "";
if (message.notification != null) {
title = "${message.notification?.title}";
body = "${message.notification?.body}";
icon = "${message.notification?.android?.imageUrl}";
if (Platform.isAndroid) {
icon = "${message.notification?.android?.imageUrl}";
} else {
icon = "${message.notification?.apple?.imageUrl}";
}
}
if (message.data['source'] == "webengage") {
isPush = true;
Map<String, dynamic> messageData =
jsonDecode(message.data['message_data']);
if (messageData.containsKey("title")) {
title = messageData["title"];
body = messageData["message"];
}
if (messageData.containsKey("expandableDetails")) {
Map<String, dynamic> expDetail = messageData["expandableDetails"];
if (expDetail.containsKey("image")) {
icon = expDetail["image"];
}
if (expDetail.containsKey("style")) {
if (expDetail['style'] == "RATING_V1" ||
expDetail['style'] == "CAROUSEL_V1") {
isPush = false;
}
}
}
if (messageData.containsKey("custom")) {
List<dynamic> customData = messageData['custom'];
print("element1: ${customData.toString()}");
customData.forEach((element) {
Map<String, dynamic> maps = element;
var key = maps['key'];
var value = maps['value'];
if (key == "itemId") {
itemId = value;
}
if (key == "type") {
type = value;
}
});
}
} else {
if (message.data.containsKey("icon")) {
icon = message.data['icon'];
}
if (message.data.containsKey("title")) {
title = message.data['title'];
body = message.data['body'];
}
if (message.data.containsKey("type")) {
type = message.data['type'];
}
if (message.data.containsKey("itemId")) {
itemId = message.data["itemId"];
}
}
if (title?.isNotEmpty == true && body?.isNotEmpty == true) {
showNotification(rand.nextInt(1000), title, body, icon,
"${type}$SEPARATOR${itemId}$SEPARATOR${icon}",
isPush: isPush);
}
}
Future<Uint8List> _getByteArrayFromUrl(String url) async {
final http.Response response = await http.get(Uri.parse(url));
return response.bodyBytes;
}
Future<void> showNotification(int notificationId, String? notificationTitle,
String? notificationContent, String? icon, String payload,
{String channelId = '1234',
String channelTitle = 'Android Channel',
String channelDescription = 'Default Android Channel for notifications',
Priority notificationPriority = Priority.high,
Importance notificationImportance = Importance.max,
bool isPush = true}) async {
//with icon
if (icon != null && icon.isNotEmpty) {
final String bigPicturePath =
await _downloadAndSaveFile(icon, 'bigPicture.jpg');
final BigPictureStyleInformation bigPictureStyleInformation =
BigPictureStyleInformation(
FilePathAndroidBitmap(bigPicturePath),
largeIcon: FilePathAndroidBitmap(bigPicturePath),
);
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
channelId, channelTitle,
channelDescription: channelDescription,
playSound: false,
importance: notificationImportance,
priority: notificationPriority,
styleInformation: bigPictureStyleInformation,
icon: 'for_icon',
);
final IOSNotificationDetails iOSPlatformChannelSpecifics =
IOSNotificationDetails(attachments: <IOSNotificationAttachment>[
IOSNotificationAttachment(bigPicturePath)
]);
final MacOSNotificationDetails macOSPlatformChannelSpecifics =
MacOSNotificationDetails(attachments: <MacOSNotificationAttachment>[
MacOSNotificationAttachment(bigPicturePath)
]);
final NotificationDetails notificationDetails = NotificationDetails(
iOS: iOSPlatformChannelSpecifics,
macOS: macOSPlatformChannelSpecifics,
android: androidPlatformChannelSpecifics);
if (isPush) {
await fitNotification.show(
notificationId,
notificationTitle,
notificationContent,
notificationDetails,
payload: payload,
);
}
} else {
//with out icon
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
channelId,
channelTitle,
channelDescription: channelDescription,
playSound: false,
importance: notificationImportance,
priority: notificationPriority,
icon: 'for_icon',
);
final NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
if (isPush) {
await fitNotification.show(notificationId, notificationTitle,
notificationContent, platformChannelSpecifics,
payload: payload);
}
}
var parts = payload.split(SEPARATOR);
var now = new DateTime.now();
var formatter = new DateFormat('yyyy-MM-dd HH:mm:ss');
String formattedDate = formatter.format(now);
NotificationModelData model = NotificationModelData(
courseId: parts[1],
icon: "$icon",
title: notificationTitle.toString(),
description: notificationContent.toString(),
type: parts[0],
notifyTime: formattedDate,
isRead: false,
id: now.millisecondsSinceEpoch.toString());
var db = AppDatabase.instance;
db.into(db.notificationModel).insert(model).then(
(value) => print(value),
);
}
Future<String> _downloadAndSaveFile(String url, String fileName) async {
final Directory directory = await getApplicationDocumentsDirectory();
final String filePath = '${directory.path}/$fileName';
final http.Response response = await http.get(Uri.parse(url));
final File file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
Future<dynamic> onSelectNotification(String? payload) async {
selectedNotificationPayload = payload;
var parts = payload!.split(SEPARATOR);
if (parts[0].toLowerCase() == "course") {
//course details page
Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, course_details,
arguments: <String, String>{
'course_id': parts[1],
'thumbnail': parts[2]
});
} else if (parts[0].toLowerCase() == "web") {
await Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, web_page,
arguments: <String, String>{'paymentUrl': "${parts[1]}"});
} else if (parts[0].toLowerCase() == "allcourse") {
Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, all_course,
arguments: <String, String>{'course_id': "${parts[1]}"});
} else if (parts[0].toLowerCase() == "plan") {
Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, plans_details_page,
arguments: <String, String>{'plan_id': "${parts[1]}"});
} else if (parts[0].toLowerCase() == "allplan") {
Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, all_plans,
arguments: <String, String>{'id': "${parts[1]}"});
} else if (parts[0].toLowerCase() == "quiz") {
Navigator.of(navigatorKey.currentState!.overlay!.context)
.pushNamed(web_page_entrance);
} else {
//notification page
await Navigator.pushNamed(
navigatorKey.currentState!.overlay!.context, notification_page);
}
}
This is my WebPage class:
var url = "";
class WebPage extends StatefulWidget {
void launchURL() async {
if (await canLaunch(url))
await launch(url);
else
throw "Could not launch $url";
}
#override
_WebPageState createState() => _WebPageState();
}
class _WebPageState extends State<WebPage>{
bool isLoading = true;
final _key = UniqueKey();
Map? _arguments;
var _webViewController;
#override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
return widget.launchURL();
});
}
#override
Widget build(BuildContext context) {
_arguments = ModalRoute.of(context)!.settings.arguments as Map?;
if (_arguments?.containsKey("paymentUrl") == true) {
url = _arguments!["paymentUrl"];
} else if (_arguments?.containsKey("course_id") == true) {
url = _arguments!["course_id"];
} else {
print(url);
}
return Scaffold(
body: SplashPage(),
);
}
}
I hope I am being clear enough. I have been stuck for days now on this particular issue with it haunting me in my dreams too. Any help would be greatly appreciated.

How to transform a Future method in a Stream method to feed a list

I have this method to feed my list, but with it i'm not able to change items dynamically ( add items, drop it...) :
loadLab(String submenu, [int limit]) async {
var parts = submenu.split('/');
var pathSlashless = parts[0].trim();
var subPathSlashless = parts.sublist(1).join('/').trim();
var snapshot = await _storage.ref().child("/${submenu}");
var retorno = await snapshot.listAll();
List<ItemLab> conteudo = [];
if(subPathSlashless.isEmpty || subPathSlashless == null){
retorno.prefixes.forEach((element) {
conteudo.add(
ItemLab(
tipo: 'PASTA',
elemento: element,
),
);
});
}
if(limit != null){
if(conteudo.length > limit){
hasMore = true;
return Stream.value(conteudo);
}else{
hasMore = false;
print("menor quen ove");
}
}
}
try {
if(subPathSlashless.isNotEmpty){
print(subPathSlashless);
List items;
await databaseReference
.collection("lab_${pathSlashless}_url")
.snapshots().forEach((element) {
element.docs.forEach((f) {
if(f.data()['videos'] != null){
items == null ? items = f.data()['videos'] :
items.addAll(f.data()['videos']);
};
print("ITEMS :::: >>> ${items}");
});
});
}catch(e){
print(e);
}
pathSlashless = null;
subPathSlashless = null;
conteudo = checkDuplicateFolder(conteudo, submenu);
print(conteudo);
return Stream.value(conteudo);
}
and the list>
return StreamBuilder(
stream: ctrlLab.loadLab(submenu),
throw this error:
type 'Future' is not a subtype of type 'Stream'
What I need to do to Make the return a Stream instead of a Future

type 'Future<dynamic>' is not a subtype of type 'Stream<dynamic>' getting data from Firebase

I'm retrieving data from Firebase Storage and Firestore, to show the items in a list with the icon (if the item is a file) or the image (if is image). The problem is, If I get all the images in one time it doesn't load all.. It loads at maximum 20 and crashes due to memory leaking. So My idea is to do a list which gets 10 elements by time, and when the user scroll down to the bottom of the results, it loads more 10 and subsequently. But, I was using Future builder and with it I cant update the list when I need and the problem continues, so now, I'm trying to get in a stream and show with a StreamBuilder to be able to update the list dynamically.
this is my controller:
loadList(String submenu, [int limit]) async {
var parts = submenu.split('/');
var pathSlashless = parts[0].trim();
var subPathSlashless = parts.sublist(1).join('/').trim();
var snapshot = await _storage.ref().child("/${submenu}");
var retorno = await snapshot.listAll();
List<ItemLab> conteudo = [];
if(subPathSlashless.isEmpty || subPathSlashless == null){
retorno.prefixes.forEach((element) {
conteudo.add(
ItemLab(
tipo: 'PASTA',
elemento: element,
),
);
});
}
for(int i = 0; i < retorno.items.length ; i++){
var url = await retorno.items[i].getDownloadURL();
conteudo.add(
ItemLab(
tipo: 'FILE',
elemento: retorno.items[i],
imageUrl: url,
),
);
if(limit != null){
if(conteudo.length > limit){
hasMore = true;
return Stream.value(conteudo);
}else{
hasMore = false;
print("less than 9");
}
}
}
try {
if(subPathSlashless.isNotEmpty){
print(subPathSlashless);
List items;
await databaseReference
.collection("lab_${pathSlashless}_url")
.snapshots().forEach((element) {
element.docs.forEach((f) {
if(f.data()['videos'] != null){
items == null ? items = f.data()['videos'] :
items.addAll(f.data()['videos']);
};
print("ITEMS :::: >>> ${items}");
});
});
for(int i = 0; i < items.length; i ++){
//print(items[i]);
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: items[i],
),
);
}
}else{
await databaseReference
.collection("lab_${pathSlashless}_url")
.snapshots().forEach((element) {
element.docs.forEach((f) {
if(f.data().isNotEmpty){
print(f.data());
if(f.data().keys.contains("videos")){
conteudo.add(
ItemLab(
tipo: 'PASTA',
pastaVideo: findFolderName(f.reference.path)
),
);
}else{
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: f.data(),
),
);
}
}
});
});
}
}catch(e){
print(e);
}
pathSlashless = null;
subPathSlashless = null;
conteudo = checkDuplicateFolder(conteudo, submenu);
return Stream.value(conteudo);
}
And here my list:
return StreamBuilder(
stream: ctrl.loadList(submenu),
builder: (ctx, snapshot) {
But, if I run this code it throws this error:
type 'Future' is not a subtype of type 'Stream'
How Can I handle that to be able to update the list dynamically using a stream instead of a Future
You can't await .snapshots(), as it returns stream, you can change it to get. Also learn more about flutter firebase realtime and normal use case, check the flutter fire docs
loadList(String submenu, [int limit]) async {
var parts = submenu.split('/');
var pathSlashless = parts[0].trim();
var subPathSlashless = parts.sublist(1).join('/').trim();
var snapshot = await _storage.ref().child("/${submenu}");
var retorno = await snapshot.listAll();
List<ItemLab> conteudo = [];
if(subPathSlashless.isEmpty || subPathSlashless == null){
retorno.prefixes.forEach((element) {
conteudo.add(
ItemLab(
tipo: 'PASTA',
elemento: element,
),
);
});
}
for(int i = 0; i < retorno.items.length ; i++){
var url = await retorno.items[i].getDownloadURL();
conteudo.add(
ItemLab(
tipo: 'FILE',
elemento: retorno.items[i],
imageUrl: url,
),
);
if(limit != null){
if(conteudo.length > limit){
hasMore = true;
return Stream.value(conteudo);
}else{
hasMore = false;
print("less than 9");
}
}
}
try {
if(subPathSlashless.isNotEmpty){
print(subPathSlashless);
List items;
(await databaseReference
.collection("lab_${pathSlashless}_url")
.get()).docs.forEach((f) {
if(f.data()['videos'] != null){
items == null ? items = f.data()['videos'] :
items.addAll(f.data()['videos']);
};
print("ITEMS :::: >>> ${items}");
});
for(int i = 0; i < items.length; i ++){
//print(items[i]);
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: items[i],
),
);
}
}else{
(await databaseReference
.collection("lab_${pathSlashless}_url")
.get()).docs.forEach((f) {
if(f.data().isNotEmpty){
print(f.data());
if(f.data().keys.contains("videos")){
conteudo.add(
ItemLab(
tipo: 'PASTA',
pastaVideo: findFolderName(f.reference.path)
),
);
}else{
conteudo.add(
ItemLab(
tipo: 'VIDEO',
elemento: null,
video: f.data(),
),
);
}
}
});
}
}catch(e){
print(e);
}
pathSlashless = null;
subPathSlashless = null;
conteudo = checkDuplicateFolder(conteudo, submenu);
return conteudo;
}
And the list
return FutureBuilder(
future: ctrl.loadList(submenu),
builder: (ctx, snapshot) {

Parsing nested json list to model fails flutter

I have search screen where i can serach text it will returns data like json below,but when i try to parse data it's not working i am getting data upto this line of codevar data = menu_list[i];,but when i pass data to model,it's not quite working,any idea what went wrong
Retrieve json from api function
Future<String> GetSearchdata(String search_text) async {
ProgressDialog dialog = CustomDialogs().showLoadingProgressDialog(context);
var response = await http.post(Urls.SEARCH_ALL,
headers: {"Content-Type": "application/json", "Authorization": token},
body: json.encode({"searchText": search_text, "language": "english"}));
Map<String, dynamic> value = json.decode(response.body);
var status = value['status'];
var msg_response = value['message'];
if (response.statusCode == 200) {
dialog.dismissProgressDialog(context);
if (status == true) {
var menu_list = value['doc'];
if(menu_list.length>0)
{
for (int i = 0; i < menu_list.length; i++) {
var data = menu_list[i];
_searchResult.add(SearchModel.fromJson(data));
}
setState(() {
print("UI Updated");
});
}
else{
final snackBar = SnackBar(content: Text("No data available"));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} else {
final snackBar = SnackBar(content: Text(msg_response));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} else {
final snackBar = SnackBar(content: Text(msg_response));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
Model
class SearchModel {
String id = "";
String name = "";
String category_name = "";
SearchModel({
this.id,
this.name,
this.category_name,
});
SearchModel.fromJson(json)
: id = json['_id'].toString(),
name = json['registrations']['name'].toString(),
category_name =json['category']['name'].toString();
}
Json
{
"status":true,
"doc":{
"registrations":[
{
"_id":"5f44b5aafc77a977e88f558c",
"name":"test shop",
"category":[
{
"name":"/Furnitue Shop"
}
]
},
{
"_id":"5f44bd1b52977b4d1411f281",
"name":"test1",
"category":[
{
"name":"/Painting"
}
]
}
]
}
}
Try my code below :
Model
class SearchModel {
String id = "";
String name = "";
String category_name = "";
SearchModel({
this.id,
this.name,
this.category_name,
});
SearchModel.fromJson(json)
: id = json['_id'].toString(),
name = json['name'].toString(),
category_name = json['category'][0]['name'].toString();
}
Retrieve json
if (response.statusCode == 200) {
dialog.dismissProgressDialog(context);
if (status == true) {
var menu_list = value['doc']["registrations"];
if(menu_list.length>0)
{
final List<SearchModel> listFromJson = menu_list.map<SearchModel>((item) => SearchModel.fromJson(item)).toList();
setState(() {
_searchResult = listFromJson;
print("UI Updated");
});
}
else{
final snackBar = SnackBar(content: Text("No data available"));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} else {
final snackBar = SnackBar(content: Text(msg_response));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} else {
final snackBar = SnackBar(content: Text(msg_response));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
Few discoveries:
1.
var menu_list = value['doc'];
This should not be
var menu_list = value['doc']['registrations'];
instead? The registrations is your list, not the doc.
2.
After you access the right element, then your model should look like this:
SearchModel.fromJson(json):
id = json['_id'].toString(),
name = json['name'].toString(),
category_name =json['category']['name'].toString();
Do note, that your category is list again (I don't know if it is intended), but if it is, then first you need to get each element from you category list and get the name of those.
Or you need something like this, if you have only 1 element there:
category_name =json['category'][0]['name'].toString();

Flutter: value of type 'Future<List<UserVideo>>' can't be assigned to a variable of type 'List<UserVideo>'

I am trying to use one List (custom type) but getting error.
When i try to use the getData() function. Like below.
List<UserVideo> videoDataList = [];
videoDataList = UserVideo.getData();
This is initState method.
#override
void initState() {
videoDataList = await UserVideo.getData();
WidgetsBinding.instance.addObserver(this);
_videoListController.init(
_pageController,
videoDataList,
);
super.initState();
}
I am getting the error.
A value of type 'Future<List<UserVideo>>' can't be assigned to a variable of type 'List<UserVideo>'.
Try changing the type of the variable, or casting the right-hand type to 'List<UserVideo>'.
Here is the code for function.
class UserVideo {
final String url;
final String image;
final String desc;
UserVideo({
this.url: mockVideo,
this.image: mockImage,
this.desc,
});
Future <List<UserVideo>> getData() async {
List<UserVideo> list = [];
try {
var deviceid = '123';
var dtgUid = '100';
var nodata;
var bodyss = {
"uid": dtgUid,
"deviceid": deviceid,
};
var url = 'http://192.168.100.4:8080/videos/get-data.php';
// Starting Web API Call.
var response = await http
.post(url, body: json.encode(bodyss))
.timeout(Duration(seconds: 5), onTimeout: () {
return null;
});
if (response.statusCode == 200) {
final data = StreamingFromJson(response.body);
if (data.count == null) {
count = 0;
} else {
count = data.count;
}
if (data.content.length > 0 && data.content[0].name != 'Empty') {
for (var i in data.content) {
list.add(UserVideo(image: i.thumbnail, url: i.video, desc: i.title));
}
} else {
nodata = 'No Record Found';
}
print(list.length);
}
} catch (e) {
print("Exception Caught: $e");
}
return list;
}
Edit:
Just showing the hardcoded value which is working fine.
static List<UserVideo> fetchVideo() {
List<UserVideo> list = [];
list.add(UserVideo(image: '', url: mockVideo, desc: 'Test1'));
list.add(UserVideo(image: '', url: mV2, desc: 'MV_TEST_2'));
list.add(UserVideo(image: '', url: mV3, desc: 'MV_TEST_3'));
list.add(UserVideo(image: '', url: mV4, desc: 'MV_TEST_4'));
return list;
}
I can use it like this and no error.
videoDataList = UserVideo.fetchVideo();
Your method getData() returns a Future:
Future<List<UserVideo>> getData() async {
List<UserVideo> list = [];
try {
var deviceid = '123';
var dtgUid = '100';
var nodata;
var bodyss = {
"uid": dtgUid,
"deviceid": deviceid,
};
You have to use async/await to call the method getData():
List<UserVideo> videoDataList = [];
videoDataList = await UserVideo.getData();
or use then():
List<UserVideo> videoDataList = [];
UserVideo.getData().then((list){
videoDataList = list;
});
Note: To use await you need to declare a method async