Adding elements to List in Flutter from For statement? - list

I'm receiving the following error while trying to add elements from my for loop to my List...
NoSuchMethodError: The method 'addAll' was called on null.
Receiver: null
Tried calling: addAll("LrWr826cd3Y")
Here is my code...
Future getData() async {
//Map videoId;
String url = 'https://Youtube API';
var httpClient = createHttpClient();
var response = await httpClient.read(url);
Map data = JSON.decode(response);
var videos = data['items']; //returns a List of Maps
List searchTitles;
List searchIds;
List searchImages;
for (var items in videos) {
//iterate over the list
Map myMap = items; //store each map
final video = (myMap['id'] as Map);
print(video['videoId']);
searchIds.addAll(video['videoId']);
final details = (myMap['snippet'] as Map);
final videoimage = (details['thumbnails'] as Map);
final medium = (videoimage['medium'] as Map);
}
setState(() { });
if (!mounted) return;
}
print(video['videoId']); successfully lists the 3 Youtube video ids as Strings. searchIds.addAll(video['videoId']); throws the error. I've tried both searchIds.add and searchIds.addAll. Where am I going wrong?
I would like to eventually push these lists to my List class here..
class CardInfo {
//Constructor
List id;
List title;
List video;
CardInfo.fromJson(List json) {
this.id;
this.title;
this.video;
}
}

You are not instantiating your searchIds object. add this
List searchIds = new ArrayList<>();
(Or)
List searchIds = new List();

Related

Comparing length of list in flutter bloc

I want to implement flutter bloc in my app. I want to compare the length of the list and trigger blocListener accordingly. But when using listenWhen, the parameter which it provides(previousState and currentState) both show the current length of the list. I expected that these two params will be giving different states through which I could compare the length of the list on different states.
BlocListener<ListBloc, ListCubitState>(
listener: (context, state){
print("new order");
},
listenWhen: (previous, current){
if(current.items.length > previous.items.length){
return true;
}
print(**current.items.length.toString()**);
print(**previous.items.length.toString()**);
return false;
},
My cubit class:
class ListBloc extends Cubit<ListCubitState>{
ListBloc(): super(ListCubitState(items: ["items", "items"]));
addItem() => emit(ListCubitState(items: addItemToList(state.items)));
removeItem() => emit(ListCubitState(items: removeItemToList(state.items)));
List<String> addItemToList(List<String> item){
List<String> newList = item;
newList.add("adsfasf");
return newList;
}
List<String> removeItemToList(List<String> item){
List<String> newList = item;
newList.removeLast();
return newList;
}
}
Could anyone suggest what's wrong in the code (or) Is there any other way to implement it?

How to convert or equalize Query<Map<String, dynamic>> to List

I have BrandList in my Firebase like this;
How can I convert or equalize this Firebase List to List.
I tried this;
var brandsRef = _firestore.collection("vehicles1").where("Brands");
List brandsList = brandsRef;
But I got this error "A value of type 'Query<Map<String, dynamic>>' can't be assigned to a variable of type 'List'."
You need to use the document Id to get the query and then you can get the data which returns a Map.
From that Map, you can supply the key to retrieve the value. In this case, the key is "Brands".
var brandsQuery = await _firestore.collection("vehicles1").doc(document Id).get();
List brandList = brandsQuery.data()["Brands"];
First I would suggest to create a model of your class Brand in addition to the jsonSerialization classics:
class Brands {
Brands({this.brandName});
List<String> brandName;
Map<String, dynamic> toMap() {
return {
'Brands': brandName,
};
}
factory Brands.fromMap(Map<String, dynamic> map) {
return Brands(
brandName: List<String>.from(map['Brands']),
);
}
String toJson() => json.encode(toMap());
factory Brands.fromJson(String source) => Brands.fromMap(json.decode(source));
}
Then you need to add a few steps to the way you retreive elements:
var response = _firestore.collection("vehicles1").where("Brands").get();
final results =
List<Map<String, dynamic>>.from(response.docs.map((e) => e.data()));
Brands brands =
results.map((e) => Brands.fromMap(e)).toList();

How to add elements dynamically in a 2d list from another list in Flutter?

I have a list of model class objects. Such as -
List<ModelChannel> allChannels = [];
I have added elements in this list from json. Model Class variables are-
final String channelid;
final String channelname;
final String channeltype;
final String categoryname;
final String channelimage;
final String channelurl;
Here categorytype contains country information. I want to divide the list country wise dynamically. I have intended to use 2d list where each row will contain all the channels of a specific country. Is this the right approach? If yes how to implement this and if not what will be the right one?
If I understand correctly, you are looking for groupBy function from collection package.
Add this package to your pubspec.yaml:
dependencies:
collection: any
And use groupBy:
import 'package:collection/collection.dart';
...
final groupByCountry = groupBy(allChannels, (ModelChannel e) => e.categoryname);
List<List<ModelChannel>> countryList = [];
List<String> channelType = [];
allChannels.forEach((element) {
if (channelType.isEmpty) {
channelType.add(element.channeltype);
} else {
if (channelType.contains(element.channeltype)) {
} else {
channelType.add(element.channeltype);
}
}
});
channelType.forEach((countryCode) {
List<ModelChannel> t = [];
allChannels.forEach((element) {
if (element.channeltype == countryCode) {
t.add(element);
}
});
countryList.add(t);
});

How to convert list getting from future method to Map<String, dynamic>

I want to convert the list coming from getPosts method (getting result from the web json and stored in the posts list) to List
Post Class
class Post {
final int userId;
final String id;
final String title;
final String body;
Post(this.userId, this.id, this.title, this.body);
}
Future<List<Post>> getPosts() async {
var data = await http
.get("https://jsonplaceholder.typicode.com/posts");
var jasonData = json.decode(data.body);
List<Post> posts = [];
for (var i in jasonData) {
Post post = Post(i["userId"], i["id"], i["title"], i["body"]);
posts.add(post);
}
return posts;
}
I tried to put the result directly to this method
static List<Map> convertToMap({List myList }) {
List<Map> steps = [];
myList.forEach((var value) {
Map step = value.toMap();
steps.add(step);
});
return steps;
}
but it's not working, I see this error
The argument type 'List<Map<dynamic, dynamic>>' can't be assigned to the parameter type 'Map<String, dynamic>'.
Change List<Map> by List<Map<String, dynamic>>
static List<Map<String, dynamic>> convertToMap({List myList }) {
List<Map<String, dynamic>> steps = [];
myList.forEach((var value) {
Map step = value.toMap();
steps.add(step);
});
return steps;
}

how to create set of item with different template in sitecore

i have a set of item under clarisonic catalog.I want to create the same set of items in another place.for example.I want to create same set of items under amazon with different template.
First i am getting all child items under clarisonic catalog and getting the name of those items.I am creating new items under Amazon with the names which i got it earlier with different template.
I want to create same set of items under amazon[all items under clarisonic catalog].
public void EntryPath(Item item)
{
List<string> ObjSiteNames = getMultiListValues(item, "Select Site");
GetChildrenSelectedItem(item, ObjSiteNames);
RecursiveItemCreation(item);
}
public List<string> getMultiListValues(Sitecore.Data.Items.Item item, string FieldID)
{
Sitecore.Data.Fields.MultilistField multiselect = item.Fields[FieldID];
return multiselect.GetItems().Select(a => a.Name).ToList();
}
public void GetChildrenSelectedItem(Item getChildredItem, List<string> sitesnmaes)
{
string defaultSitePath = "/sitecore/content/Administration/Sites";
masterDb = Sitecore.Configuration.Factory.GetDatabase("master");
templateItem = masterDb.GetItem("/sitecore/templates/User Defined/SC-DW Data/Generic/Widgets/NavigationItem");
foreach (string str in sitesnmaes)
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append(defaultSitePath).Append("/").Append(str);
itemDesPath = masterDb.GetItem(strBuilder.ToString());
}
}
public void RecursiveItemCreation(Item Getchilds)
{
foreach (Item i in Getchilds.GetChildren())
{
i.Template = masterDb.GetItem("/sitecore/templates/User Defined/SC-DW Data/Generic/Widgets/NavigationItem").
if ((i.HasChildren))
{
}
else
{
itemDesPath.Add(i.Name, templateItem);
foreach (Item ItemDes in itemDesPath.Axes.GetDescendants())
{
if (ItemDes.Name == i.Name)
{
ItemDes.Editing.BeginEdit();
ItemDes.Fields["Datasource"].Value = i.Paths.Path;
ItemDes.Editing.EndEdit();
}
}
}
}
From what I understand you want to copy the whole tree below Clarisonic Catalog item to the Amazon node. The only difference is that the created items should use different template (/sitecore/templates/User Defined/SC-DW Data/Generic/Widgets/NavigationItem).
Code below should do the job. I haven't tested it but I'm sure you can solve all the problems you'll encounter.
public void CopyTreeStructure(Item source, Item target)
{
// find the new template you want to use
TemplateItem newTemplate = new TemplateItem(source.Database.GetItem("/sitecore/templates/User Defined/SC-DW Data/Generic/Widgets/NavigationItem"));
foreach (Item child in source.Children)
{
// create the copy of original item using new template
Item copiedItem = CreateItemUsingNewTemplate(child, target, newTemplate);
// repeat for all descendants recursively
CopyTreeStructure(child, copiedItem);
}
}
private Item CreateItemUsingNewTemplate(Item source, Item targetParent, TemplateItem templateToUse)
{
// create item
Item copiedItem = targetParent.Add(source.Name, templateToUse);
// pre-read all fields
source.Fields.ReadAll();
using (new EditContext(copiedItem))
{
// update all the fields of new item
foreach (Field field in source.Fields)
{
copiedItem[field.Name] = source[field.Value];
}
}
// return copied item so we can copy it's descendants
return copiedItem;
}