Flutter: Search inside the List - flutter

I am trying to using the mobile_number plugin. Basically, I am fetching the SimCard number.
Here is the code.
String _mobileNumber = '';
List<SimCard> _simCard = <SimCard>[];
Future<void> initMobileNumberState() async {
if (!await MobileNumber.hasPhonePermission) {
await MobileNumber.requestPhonePermission;
return;
}
String mobileNumber = '';
// Platform messages may fail, so we use a try/catch PlatformException.
try {
mobileNumber = await MobileNumber.mobileNumber;
_simCard = await MobileNumber.getSimCards;
} on PlatformException catch (e) {
debugPrint("Failed to get mobile number because of '${e.message}'");
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_mobileNumber = mobileNumber;
});
}
Widget fillCards() {
List<Widget> widgets = _simCard
.map((SimCard sim) => Text(
'Sim Card Number: (${sim.countryPhonePrefix}) - ${sim.number}\nCarrier Name: ${sim.carrierName}\nCountry Iso: ${sim.countryIso}\nDisplay Name: ${sim.displayName}\nSim Slot Index: ${sim.slotIndex}\n\n'))
.toList();
return Column(children: widgets);
}
This is working fine I can see the mobile number.
But now I need to search the number inside the list.
I checked some of the questions on SO to get it done but I am not good with lists.
I tried using some of the examples and comes up with below. But this is incorrect with so many errors.
var comparenumber = _simCard.map((SimCard sim).where((sim.number) => sim.number.toLowerCase().contains(mobile.toLowerCase()).toList();

If you want to search if the list has a number or part of a number (say the result would be true searching for 641 in a list that has a number 641-819-xxxx)
you can use this code
bool searchNumber(String number) {
return _simCard.where((element) => element.number.contains(number)).isNotEmpty;
}
if you want to search for an exact number match replace element.number.contains(number) with element.number == number as in dart == for strings compare the string value, not pointers as in Java for example.
So, what is where?
where is a function in the abstract class Iterable (and lists in dart are iterable) that take a predicate or a test function and returns an iterable that has only elements that match the predicate.
returned iterable can be collected to a list or you can use some other functions or properties directly on it like isNotEmpty in our case

Related

Getting data from Realtime Database with a conditional statement

how I can show DeliveryBoys in a specific location, in my realtime database I have a value that I need to compare drivers with which is "City" I would like to have all DeliveryBoys that are in a specific city. How can I do that? Using flutter
Am only able to get all drivers without a conditional statement
**This is my Function that i want to modify **
retrieveOnlineDriversInformation(List onlineNearestDriversList) async {
DatabaseReference ref =
FirebaseDatabase.instance.ref().child("DeliveryBoys");
for (int i = 0; i < onlineNearestDriversList.length; i++) {
await ref
.child(onlineNearestDriversList[i].driverId.toString())
.once()
.then((dataSnapshot) {
var driverKeyInfo = dataSnapshot.snapshot.value;
dList.add(driverKeyInfo);
});
}
}
Database Structure
Based on your responses and as far as I can see, you don't need the loop where you have it. Therefore, I am going to ignore it and simply show you the code that will return the list of driver ids of all drivers for city 'Lusaka'.
Future<List<String>> retrieveOnlineDriversInformation() async {
final driverIds = <String>[];
DatabaseReference ref = FirebaseDatabase.instance.ref().child("drivers");
try {
await ref.orderByChild("city")
.equalTo("Lusaka")
.once()
.then(
(event) {
if (event.snapshot.value != null) {
final driverListData =
Map<String, dynamic>.from(event.snapshot.value! as Map);
driverListData.forEach((key, value) {
driverIds.add(key);
});
}
},
} on FirebaseException catch (error, stackTrace) {
// < Some code here to print database error details or otherwise deal with it >
} catch (error, stackTrace) {
// < Some code here to print other error details or otherwise deal with it >
}
return driverIds;
}
You could instead modify this to just return the Map 'driverListData' which contains each driver's id and associated driver data.
A couple of other points:
You don't stick to a standard naming convention for your database node and field names. I suggest that you always use lowerCamelCase as the standard (so for example, change DriverLicense to driverLicense) as it will match what you typically name the variables within the Flutter/Dart code.
You don't need to hold the driver id as a separate field in the driver node. It is a duplicate (and therefore wastes space on the database) of the driver record key, which is already accessible to you.
As you see, you should always wrap your database call logic in a try / catch clauses in order to handle any errors that the call to the database may return. There are specific exceptions that can be tested for with the on clause.

Flutter merge search queries?

We have a Laravel + Flutter based platform.
When a search query is returned in our Flutter application, it prints the products on the screen by making an API call as follows.
api/foods?search=EXAMPLE;&searchFields=name:like;&limit:70;
Our search is sorted by name.
When I search for "EXAMPLE", I want a listing based on the name, followed by products with "EXAMPLE" in the description. So this query;
api/foods?search=EXAMPLE;&searchFields=description:like;&limit:70;
I mean, having these two queries done one after the other; How can I list it in the search results so that it lists the name first and then the description?
yani EXAMPLE aramasının sonucunda
önce "api/foods?search=EXAMPLE;&searchFields=name:like;&limit:70;" sorgusu,
altında da birleşik bir şekilde "api/foods?search=EXAMPLE;&searchFields=description:like;&limit:70;" sorgusunun yer almasını istiyorum.
Flutter Codes;
Future<Stream<Food>> searchFoods(String search) async {
Uri uri = Helper.getUri('api/foods');
Map<String, dynamic> _queryParams = {};
_queryParams['search'] = '$search';
_queryParams['searchFields'] = 'name:like;';
_queryParams['limit'] = '70';
uri = uri.replace(queryParameters: _queryParams);
try {
final client = new http.Client();
final streamedRest = await client.send(http.Request('get', uri));
return streamedRest.stream.transform(utf8.decoder).transform(json.decoder).map((data) => Helper.getData(data)).expand((data) => (data as List)).map((data) {
return Food.fromJSON(data);
});
} catch (e) {
print(CustomTrace(StackTrace.current, message: uri.toString()).toString());
return new Stream.value(new Food.fromJSON({}));
}
}
One option is to have 2 ListViews in the Column so that you can display results from 2 lists. The other option is to merge the list into one and then send it to your UI to display in single ListView.

Problems reading Bluetooth Device data and returning it into code in Flutter/Dart

The following is the function code I am using to read the data from the Bluetooth Device
Future listServices() async {
List<BluetoothService>? services = await primBms?.device.discoverServices();
List values = [];
services?.forEach((service) async {
if (service.uuid.toString() == primBmsUuids[0]) {
for (BluetoothCharacteristic c in service.characteristics) {
List<int> value = await c.read();
int val = int.parse(String.fromCharCode(value[0]) + String.fromCharCode(value[1]));
print(value);
print(val);
values.add(val);
}
}
});
return values;
}
I am parsing the character codes from the read data packet, however using this function returns an empty list. I used a print function to confirm whether value and val return valid values and they do, however for whatever reason these do not get added to the list.
Can someone kindly help me figure out the solution to my problem ?

Multiple local HMS ML Kit translator models in Flutter?

I've defined a class that wraps the HMS ML Kit in-device translator.
This class has two translator instances, with two different settings:
MLLocalTranslator translatorSend = new MLLocalTranslator();
MLLocalTranslator translatorReceive = new MLLocalTranslator();
MLTranslateSetting settingSend = new MLTranslateSetting();
MLTranslateSetting settingReceive = new MLTranslateSetting();
translatorSend translates request from a language (for example it) to English (en). translatorReceive translates the response of the request from en to it.
However, the prepare method only downloads the model for en_it translation and not the it_en model (if exists).
HMSTranslator(String languageCode) {
settingSend.sourceLangCode = languageCode;
settingSend.targetLangCode = "en";
settingReceive.sourceLangCode = "en";
settingReceive.targetLangCode = languageCode;
}
Future<bool> prepare() async {
if(settingSend.sourceLangCode != settingSend.targetLangCode) {
bool isSendPrepared = await translatorSend.prepareModel(setting: settingSend)
bool isReceivePrepared = await translatorReceive.prepareModel(setting: settingReceive);
isPrepared = isSendPrepared && isReceivePrepared;
}
else {
isPrepared = false;
}
return isPrepared;
}
The problem comes when I translate a string with translatorSend.
Future<String> translateString(String stringToTranslate) async {
if(settingSend.sourceLangCode != settingSend.targetLangCode) {
String result;
if (isPrepared) {
result = await translatorSend.asyncTranslate(sourceText: stringToTranslate);
}
else {
settingSend.sourceTextOnRemote = stringToTranslate;
result = await sendRemoteTranslator.asyncTranslate(setting: settingSend);
}
return result;
}
else {
return stringToTranslate;
}
}
This method should translate an it String to an en String. However, it seems to call the en_it model and fails the translation:
I/flutter (28228): TRANSLATOR: it to en
I/flutter (28228): TRANSLATOR: PREPARED
I/MLLocalTranslator(28228): translate sourceLanguage: en targetLanguage: it
WHAT: vestiti usati -> vestiti usati - WHERE applicazione -> applicazione
The translation of the response, from en to it works.
I've tested other languages and that happens also with fr.
Further testing showed that the process worked with es:
WHAT: ropa usada -> Used clothing - WHERE aplicación -> application
Pls check whether you are using the new version of the Flutter plug-in.
Language packs can be used in two-way. For example, en-it can be used for en to it or it to en.
The following are for your reference:
Modify based on the plugin Demo in the official website
The same instance is used for bidirectional translation by invoking multiple times.
//Entry function
_translationMake() async {
try {
await _prepareModel_run("it","en","vestiti usati");
await _prepareModel_run("en","it","application");
} on Exception catch (e) {
print(e.toString());
}
}
_prepareModel_run(String srcLang, String dstLang, String content) async {
setting.sourceLangCode = srcLang;
setting.targetLangCode = dstLang;
try {
final bool res = await translator.prepareModel(setting: setting);
if (res) {
final String s = await _localTranslate_run(content);
if (s != null) {
print("_prepareModel_run " + content + " translate to "+s);
}
}else {
print("_prepareModel_run res false");
}
} on Exception catch (e) {
print(e.toString());
}
}
Future<String> _localTranslate_run(String Content) async {
try {
final String s =
await translator.syncTranslate(sourceText: Content);
if (s != null) {
_stopLocalTranslate();
setState(() => _translateResult = s);
return s;
} else {
print("no Translation");
setState(() => _translateResult = "no translation");
return "no translation";
}
} on Exception catch (e) {
print(e.toString());
}
}
And the log print results are as follows:
_prepareModel_run vestiti usati translate to Used clothes
_prepareModel_run application translate to applicazione
We can use HMS ML kit to translate text into different languages. The following is the info. you can take reference for.
ML services can currently translate texts between 12 languages: Simplified Chinese, English, French, Arabic, Thai, Spanish, Turkish, Portuguese, Japanese, German, Italian, and Russian.
Step 1: Text is fetched from UI and provided to ML model
Step 2: Parameters are set before making API call to server
    · Source language code
    · Desired Language code
    · String which needs to be translated.
Step 3: Once API data reaches the server ML Model translates the text into desired output
Step 4: Server returns the translated output to application.
Step 5: Application shows output to UI.
Precautions: The machine learning model is stored on cloud. An Internet call is made so its permission is required.
Below are the changes you have to do in order to run build and run the project
Open App.gradle file and add this line on top.
apply plugin: 'com.huawei.agconnect'
To use Text Translation service add this dependency to pro
mplementation 'com.huawei.hms:ml-computer-translate:1.0.3.300'
MLRemoteTranslateSetting object is being created which takes Source Language as setSourceLangCode() and Output Language as setTargetLangCode()
MLRemoteTranslator object is created by passing previously created MLRemoteTranslateSetting object to it.
You can create a Task where mlRemoteTranslator will have an async call by asyncTranslate() and we will provide user string as the input to this method.
This task will yield to 2 callbacks
addOnSuccessListener
addOnFailureListener
As the name suggests you can add your code in success listener and can add notification/Log in failure listener.
For Flutter:
First:
create MlTranslatorSettings object and instance in initState
Second:
set the settings to the translator, for example, initial language and final language of the translation, see below example.
In the properties, you can customize the type of map, controls, camera position, initial position, etc.
Here are also some detailed info. regarding how to use HMS ML kit with Flutter:
Link Hope it will be helpful to you.

Flutter, getting database records and then internet json

I have a simple table from which I'm fetching a list of records. Once I get the records, then I have to get information online for each of the records. The code to do this is as follows:
class UserStationList {
List<UserStationListItem> _userStations = [];
final StreamController<HomeViewState> stateController;
UserStationList({#required this.stateController});
Future fetchUserStations() async {
stateController.add(HomeViewState.Busy);
//Fetch stations from table.
List<Map<String, dynamic>> stations =
await UserStationDatabase.instance.queryAllRows();
//If there are no stations, return and tell the screen to display the no data message.
if (stations.length == 0) {
stateController.add(HomeViewState.NoData);
return;
}
//Loop through each of the stations in the list and build the collection.
stations.forEach((station) async {
UserStationListItem newItem =
await _getPurpleAirSiteData(station['_id'], station['stationid']);
_userStations.add(newItem);
});
//When done, let the screen know.
stateController.add(HomeViewState.DataRetrieved);
}
Future<UserStationListItem> _getPurpleAirSiteData(
int id, int stationId) async {
var response = await http.get('$kURL$stationId');
var data = json.decode(response.body);
return UserStationListItem(
id: id, stationId: stationId, stationName: data['results'][0]['Label']);
}
}
The problem that I am running into involves the futures. I am processing the loop in a forEach and calling into the _getPurpleAirSiteData function for each. Within that function I have to await on the http.get to bring in the data. The stateController.add(HomeViewState.DataRetrieved) function is being called and the function exits long before the loop is completed. This is resulting in the data not being available when the StreamBuilder that I have receiving the data is run.
How can I set this up so that the loop runs completely before calling stateController.add?
I would change this part of code to a list of Futures and await-ing on it.
//Loop through each of the stations in the list and build the collection.
stations.forEach((station) async {
UserStationListItem newItem =
await _getPurpleAirSiteData(station['_id'], station['stationid']);
_userStations.add(newItem);
});
To:
List<Future<UserStationListItem>> listOfFutures = [];
stations.forEach((station) {
listOfFutures.add(_getPurpleAirSiteData(station['_id'], station['stationid']));
});
var stationItems = await Future.wait(listOfFutures);
stationItems.forEach((userStationListItem) {
_userStations.add(userStationListItem);
});
What I am essentially doing creating a list of Futures with your server request. Then await on it which returns a list of item result Maintaining index, which in turn ensures that requests are completed before you hit statecontroller.add. You also gain a performance gain since all request are not going one by one and instead asynchronously. Then you just iterate through the future result and add it to your item list.