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?
Related
I've got an Abstract class named QuizzAnswer and I've a class named QuizzAnswerMCQ which extends QuizzAnswer class.
abstract class QuizzAnswer extends Equatable {}
class QuizzAnswerMCQ extends QuizzAnswer {
String optionId;
bool isSelected;
QuizzAnswerMCQ({required this.optionId, required this.isSelected});
#override
List<Object?> get props => [optionId, isSelected];
Map<String, dynamic> toJson() => {
"option_id": optionId,
"is_selected": isSelected,
};
}
and I've got a list which is of type QuizzAnswerMCQ
List<QuizzAnswerMCQ> quizAnswerList=[];
and I add items to the list
quizAnswerList.add(QuizzAnswerMCQ(
optionId: event.optionId, isSelected: event.optionValue));
what I want to do is to check if the optionId is already there in the list or not so I wrote this,
if(quizAnswerList.map((item) => item.optionId).contains(event.optionId)){
print ('EXISTTTTSSSSS');
}else{
print('DOESNT EXISTTTT');
}
Even though the optionId is there,I still get the output 'DOESNT EXISTTTT'.Please help!!!
Do this
if (quizAnswerList
.where((element) => element.optionId == event.optionId)
.isNotEmpty) {
print ('EXISTTTTSSSSS');
}
else{ print('DOESNT EXISTTTT'); }
the .where() method checks and creates a list so if it's not empty then that item exists
You can use firstWhere like this
result = quizAnswerList.firstWhere((item) => item.optionId == your_id);
or checking from other List
result = quizAnswerList.firstWhere((item) => otherList.contains(item));
then
if(result.length > 0){
print ('');
}else{
print(');
}
Official doc here
dart code where i try to add element in messages to finalList (Don't work)
List<Message> finalList = List(); //list where data should go
if (tmp != null) {
List<dynamic> messages = tmp["messages"]; //list where data come from
for (var element in messages) {
try {
Message eltMsg = Message.fromMap(element);
finalList.add(eltMsg);
} catch (e) {
print(e);
}
}
finalList.sort((a, b) => b.createdAt.compareTo(a.createdAt));
}
I assume the fromMap method accepts a Map<String, dynamic>, so if you are sure that the content of tmp["messages"] actually is a map, you can do the following:
final messages = List<Map<String, dynamic>>.from(tmp["messages"] as List<dynamic>);
List<Message> finalList = messages.map((m) => Message.fromMap(m)).toList();
finalList.sort((a, b) => b.createdAt.compareTo(a.createdAt));
As long as your implementation of Message.fromMap is correct, this should get you a list of messages.
In List One, I am getting some items. Each time those items are changing. Sometimes, I can get more than one record in the List.
In a second List, I would like to store all the data of List One. So, I can then display all the items of List Two.
To make it more clear.
List One = "/temp/file1.jpeg"
List Two = "/temp/file1.jpeg"
List One = "/temp/file2.jpeg"
List Two = "/temp/file1.jpeg,/temp/file2.jpeg"
I have tried this
void _openDocumentFileExplorer({fileType: FileType.custom}) async {
setState(() => _loadingPath = true);
try{
_paths = (await FilePicker.platform.pickFiles(
type: fileType,
allowMultiple: true,//_multiPick,
allowedExtensions: ['pdf']))?.files;
} on PlatformException catch (e) {
print("Unsupported operation" + e.toString());
} catch (ex) {
print('$ex');
}
if (!mounted) return;
setState(() {
_loadingPath = false;
_fileName = _paths != null ?
_paths!.map((e) => e.name).toString() : '...';
});
}
ListView.separated(
itemCount:
_paths != null && _paths!.isNotEmpty
? _paths!.length
: 1,
itemBuilder:
(BuildContext context, int index) {
final bool isMultiPath =
_paths != null && _paths!.isNotEmpty;
final String name = _paths!
.map((e) => e.name)
.toList()[index];
//filesGB store the full path + the file name
final filesGB = _paths!
.map((e) => e.path)
.toList()[index]
.toString();
print (filesGB);
_paths?.addAll(allFiles!.map((e) ));
allFiles.addAll(filesGB.toList());
allFiles.addAll(filesGB);
// allFilesV2.addAll(filesGB);
but it does not work. I am getting this error message.
"The argument type 'String' can't be assigned to the parameter type 'Iterable'"
Please, do you have any suggestion?
I think you can use SPREAD OPERATOR (...) using a triple dot for merging one array into another.
For example:
List list1= ["/temp/file1.jpeg"];
List list2 = [];
after some time
list1 = ["/temp/file2.jpeg"];
so whenever your list one change do
list2 = [...list2,...list1];
print(list2);
output: ["/temp/file1.jpeg","/temp/file2.jpeg"]
I think it would help.
I have a code working good, but i am trying to do an enhancement
https://trycf.com/gist/5fdbccd52121856991e6fe3f82307d34/lucee5?theme=monokai
in the above, i am trying if the deleted item in list is IN, it should also delete the other item starting with I letter
The code is looping for the list elements and doing a match to detect and delete the element
Source
<cfscript>
i = 'AS,AK,SK,SB,IN,IP';
Y = 'IN';
local.X = [];
listEach(I, function(value, index) {
if (!listFindNoCase(Y, value)) {
arrayAppend(X, value);
}
});
dump(x);
</cfscript>
You can do that by checking before if the list contains your element using listFindNoCase, then using listFilter to filter the items you do not want in your new list, something like this:
<cfscript>
originalList = 'AS,AK,SK,SB,IN,IP';
needle = 'IN,AS';
newList = originalList;
listEach(needle, function(needle) {
if (listFindNoCase(newList, needle)) {
newList = listFilter(newList, function(value) {
return lcase(left(value, 1)) != lcase(left(needle, 1));
});
}
});
dump(newList);
</cfscript>
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();