Valid value range is empty: 0 - flutter

my function search for a specifies pharmacy's and add these to my List of Map but my list still empty in the return
Future<List<Map>> geto(String s) async{
var user_position = await _locationService1.GetCurrentPosition();
print(user_position.latitude) ;
print(user_position.longitude) ;
List <Map> pp =[] ;
await FirebaseFirestore.instance.collection('pharma')
.get().then((value) => {
value.docs.forEach((pharma) async{
print(pharma.id) ;
await FirebaseFirestore.instance.collection('pharma')
.doc(pharma.id)
.collection('med')
.get().then((med) => {
med.docs.forEach((element) async{
if(element['qtc'] >0 && element.id.toString().toLowerCase()==s.toLowerCase()){
print(element.data()) ; // printer le nom de med
print(pharma['nom']) ; // printer la pharma de med avant
// print(pharma['latitude']) ; // acceder a un champ de pharma
var d = Geolocator.distanceBetween(
(pharma)['latitude'],
(pharma)['longitude'],
user_position.latitude,
user_position.longitude,
);
pp.add({'id' : pharma.id , 'distance' : d}) ;
print('Cest la list felicitation $pp') ;
}
})
});
})
})
;
print("--------------------...........................${pp.length}") ;
return pp ;
}
-I tried Future Builder and pass the function as the futur argument but it's didn't work and return a red screen which tell me that the list is empty

Related

Unable to return list of object from Future

I am performing a firebase query and I want to return a list of object afect going though my for loop.But the process stoped in for loop and doesn't return anything.I am also using get package to show data at screen after casting the furture function into stream data.
Now I want to know how to well return this list inside Future function.Thank you very much if you can tell me how.
Future<List<InfoCompagnie>> fetchCompanies(
String depart, String arrivee, String jour, int place) async {
var firstCaseDate = jour.inCaps;
var codedDepart = depart.substring(0, 3).toUpperCase();
var codedArrivee = arrivee.substring(0, 3).toUpperCase();
List<InfoCompagnie> compagnieList = List<InfoCompagnie>();
await db
.collection('DISPONIBILITE')
.document('FzxJ0eta1xIcSFyxd9nE')
.get()
.then((DocumentSnapshot event) {
for (var compagnie in event.data[firstCaseDate]) {
db
.collection('PLACE')
.document(compagnie)
.collection('$codedDepart-$codedArrivee')
.document(firstCaseDate)
.collection('Bus')
.where('PlaceDisponible', isGreaterThanOrEqualTo: 1)
.getDocuments()
.then((QuerySnapshot event) {
if (event.documents.length > 0) {
for (var data in event.documents) {
var infoCompagnie = InfoCompagnie().obs;
//Obtention du nomble de place disponible pour le voyage ici
accessiblePlace = data.data['PlaceDisponible'];
codeBus = data.data['CodeBus'];
infoCompagnie.update((value) {
value.accessiblePlace = accessiblePlace;
});
//Obtention de la classe du bus de voyage ici;
db
.collection('VEHICULE')
.where('CodeBus', isEqualTo: codeBus)
.getDocuments()
.then((QuerySnapshot event) {
for (var data in event.documents) {
classe = data.data['Classe'];
infoCompagnie.update((value) {
value.classe = classe;
});
}
});
//Obtention des info de la compagnie ici compagnie ici
db
.collection('COMPAGNIE')
.where('Code', isEqualTo: compagnie)
.getDocuments()
.then((QuerySnapshot event) {
for (var data in event.documents) {
companieName = data.data['Nom'];
companieCode = compagnie;
infoCompagnie.update((value) async {
value.companieName = companieName;
value.companieCode = companieCode;
value.travelNumber = getTravelNumber(companieCode);
});
}
});
//Obtention de l'horaire de voyage ici
db
.collection('PLACE')
.document(compagnie)
.collection('$codedDepart-$codedArrivee')
.getDocuments()
.then((element) {
for (var data in element.documents) {
//Obtention du montant du ticket de voyage ici
if (data.documentID == 'Montant') {
amount = data.data['Montant'];
infoCompagnie.update((value) {
value.amount = amount;
});
} else if (data.documentID == 'Horaire') {
infoCompagnie.update((value) {
//Obtention de l'horaire de voyage ici
value.departureHoure = data.data['HeureDépart'];
value.arrivalHoure = data.data['HeureArrivée'];
});
} else {
var days = {
'Lundi',
'Mardi',
'Mercredi',
'Jeudi',
'Vendredi',
'Samedi',
'Dimanche'
};
if (days.contains(data.documentID)) {
db
.collection('PLACE')
.document(compagnie)
.collection('$codedDepart-$codedArrivee')
.document(data.documentID)
.collection('Bus')
.where('PlaceDisponible', isGreaterThanOrEqualTo: 1)
.getDocuments()
.then((bus) {
if (bus.documents.length > 0) {
for (var busInfo in bus.documents) {
infoCompagnie.update((value) {
value.othersPlaces[data.documentID] =
busInfo.data['PlaceDisponible'];
});
}
}
});
}
}
}
});
compagnieList.add(infoCompagnie.value); //Adding to list here
} //Fin for de compagnie
} //Sortie de condition if
});
} //Fin for
});
return compagnieList; //Return my list here
}

How to match loop a single character with multiple characters in a list and return bigger list dart?

I'm new in flutter and don't know much about dart, and i want ask about my problem.
This my example to graft each character * in listb loop foreach element in lista:
void main() {
var lista = ['1', '2', '3'];
var listb = ['a***' ,'b*','c'];
List<String> filter1 = [];
List<String> filter2 = [];
List<String> filter3 = [];
//
for (var value in listb) {
if (value.contains("*")) {
for (var aa in lista) {
filter1.add( value.replaceFirst('*', '$aa'));
}
}
}
listb.removeWhere((aaa) => aaa.contains('*'));
filter1 = List.from(filter1)..addAll(listb) ;
print('filter1' + '$filter1');
//
for (var value in filter1) {
if (value.contains("*")) {
for (var aa in lista) {
filter2.add( value.replaceFirst('*', '$aa'));
}
}
}
filter1.removeWhere((aaa) => aaa.contains('*'));
filter2 = List.from(filter2)..addAll(filter1) ;
print('filter2' + '$filter2');
//
for (var value in filter2) {
if (value.contains("*")) {
for (var aa in lista) {
filter3.add( value.replaceFirst('*', '$aa'));
}
}
}
filter2.removeWhere((aaa) => aaa.contains('*'));
filter3 = List.from(filter3)..addAll(filter2) ;
print('filter3' + '$filter3');
}
Result out put
filter1[a1**, a2**, a3**, b1, b2, b3, c]
filter2[a11*, a12*, a13*, a21*, a22*, a23*, a31*, a32*, a33*, b1, b2, b3, c]
filter3[a111, a112, a113, a121, a122, a123, a131, a132, a133, a211, a212, a213, a221, a222, a223, a231, a232, a233, a311, a312, a313, a321, a322, a323, a331, a332, a333, b1, b2, b3, c]
And it's very bad if character * to be replace in listb is : "a***********" :))
Is there a shotter way to escape one character need replace is a loop to have result filter3 at output? Thks U!
Darish's answer is a cool application of set theory, though I would argue that it is overkill. You can also achieve this with listB.expand and a recursive generator method:
void main() {
final listA = ['1', '2', '3'];
final listB = ['a***', 'b*', 'c'];
final output = listB.expand((term) => permutationGenerator(term, listA)).toList();
print(output);
}
Iterable<String> permutationGenerator(String input, List<String> replacements) sync* {
if (input.length == 0) {
// If the input is empty, there's nothing to generate
return;
}
if (input.length == 1) {
// If the input is one character, there's no suffix to append
if (input == '*') {
// Input is '*' so yield all the values in replacements
yield* replacements;
} else {
// Input isn't '*' so just yield it alone
yield input;
}
}
// Trim off and cache the first character
String firstChar = input[0];
// Recursively process all possible permutations of the input minus
// the first character
for (var suffix in permutationGenerator(input.substring(1), replacements)) {
if (firstChar == '*') {
// If the first character is '*', replace it with all values in
// replacements and append to it the suffix values calculated
// from the recursive
yield* replacements.map((c) => c + suffix);
} else {
// The first character isn't '*' so just yield it directly
yield firstChar + suffix;
}
}
}
This will output the following list (formatted):
[
a111,
a211,
a311,
a121,
a221,
a321,
a131,
a231,
a331,
a112,
a212,
a312,
a122,
a222,
a322,
a132,
a232,
a332,
a113,
a213,
a313,
a123,
a223,
a323,
a133,
a233,
a333,
b1,
b2,
b3,
c,
]
You can create a general solution by taking Cartesian product of the input strings.
Step 1:
These are the input lists.
var lista = ['1', '2', '3'];
var listb = ['a***' ,'b*','c'];
Split each 'listb' item as shown below
listb.forEach((value) {
///split the string with asterisk symbol
var symbols = value.split('*');
}
Step 2:
For each asterisk symbol, calculate the Cartesian product of the input strings.
Iterable<List<String>> product = cartesian(
List<List<String>>.generate(symbols.length-1, (tempIndex) => lista));
product.forEach((productValue) {
///final output
print("$symbol${productValue.join()}");
});
The complete snippet is here.
void main() {
///strings that we should use for permutation
var lista = ['1', '2', '3'];
///input strings with asterisk that needs to be replaced.
var listb = ['a***', 'b*', 'c'];
listb.forEach((value) {
///split the string with asterisk symbol
var symbols = value.split('*');
for (int i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
if (symbol.isNotEmpty) {
Iterable<List<String>> product = cartesian(
List<List<String>>.generate(symbols.length-1, (tempIndex) => lista));
product.forEach((productValue) {
///final output
print("$symbol${productValue.join()}");
});
}
}
});
}
Iterable<List<T>> cartesian<T>(List<List<T>> inputs) sync* {
if (inputs.isEmpty) {
yield List<T>(0);
return;
}
var indices = List<int>.filled(inputs.length, 0);
int cursor = inputs.length - 1;
outer:
do {
yield [for (int i = 0; i < indices.length; i++) inputs[i][indices[i]]];
do {
int next = indices[cursor] += 1;
if (next < inputs[cursor].length) {
cursor = inputs.length - 1;
break;
}
indices[cursor] = 0;
cursor--;
if (cursor < 0) break outer;
} while (true);
} while (true);
}
The output is
a111
a112
a113
a121
a122
a123
a131
a132
a133
a211
a212
a213
a221
a222
a223
a231
a232
a233
a311
a312
a313
a321
a322
a323
a331
a332
a333
b1
b2
b3
c
You can see a live demo here on DartPad.

Format string to phone number with (123) 456-6789 pattern using dart

Here is my code
void main() {
String phoneNumber = '123456789';
String formattedPhoneNumber = phoneNumber.replaceFirst("(\d{3})(\d{3})(\d+)", "(\$1) \$2-\$3");
print('Formatted number ${formattedPhoneNumber}');
}
Output:
Formatted number 123456789
I want output as Formatted number (123) 456-6789
Try this
print('1234567890'.replaceAllMapped(RegExp(r'(\d{3})(\d{3})(\d+)'), (Match m) => "(${m[1]}) ${m[2]}-${m[3]}"));
Create a custom Masked class
import 'package:flutter/material.dart';
class MaskedTextController extends TextEditingController {
MaskedTextController({String text, this.mask, Map<String, RegExp> translator})
: super(text: text) {
this.translator = translator ?? MaskedTextController.getDefaultTranslator();
this.addListener(() {
var previous = this._lastUpdatedText;
if (this.beforeChange(previous, this.text)) {
this.updateText(this.text);
this.afterChange(previous, this.text);
} else {
this.updateText(this._lastUpdatedText);
}
});
this.updateText(this.text);
}
String mask;
Map<String, RegExp> translator;
Function afterChange = (String previous, String next) {};
Function beforeChange = (String previous, String next) {
return true;
};
String _lastUpdatedText = '';
void updateText(String text) {
if(text != null){
this.text = this._applyMask(this.mask, text);
}
else {
this.text = '';
}
this._lastUpdatedText = this.text;
}
void updateMask(String mask, {bool moveCursorToEnd = true}) {
this.mask = mask;
this.updateText(this.text);
if (moveCursorToEnd) {
this.moveCursorToEnd();
}
}
void moveCursorToEnd() {
var text = this._lastUpdatedText;
this.selection = new TextSelection.fromPosition(
new TextPosition(offset: (text ?? '').length));
}
#override
void set text(String newText) {
if (super.text != newText) {
super.text = newText;
this.moveCursorToEnd();
}
}
static Map<String, RegExp> getDefaultTranslator() {
return {
'A': new RegExp(r'[A-Za-z]'),
'0': new RegExp(r'[0-9]'),
'#': new RegExp(r'[A-Za-z0-9]'),
'*': new RegExp(r'.*')
};
}
String _applyMask(String mask, String value) {
String result = '';
var maskCharIndex = 0;
var valueCharIndex = 0;
while (true) {
// if mask is ended, break.
if (maskCharIndex == mask.length) {
break;
}
// if value is ended, break.
if (valueCharIndex == value.length) {
break;
}
var maskChar = mask[maskCharIndex];
var valueChar = value[valueCharIndex];
// value equals mask, just set
if (maskChar == valueChar) {
result += maskChar;
valueCharIndex += 1;
maskCharIndex += 1;
continue;
}
// apply translator if match
if (this.translator.containsKey(maskChar)) {
if (this.translator[maskChar].hasMatch(valueChar)) {
result += valueChar;
maskCharIndex += 1;
}
valueCharIndex += 1;
continue;
}
// not masked value, fixed char on mask
result += maskChar;
maskCharIndex += 1;
continue;
}
return result;
}
}
Now call it in your main dart file
var maskedController = MaskedTextController(mask: '(000) 000-0000');
TextField(
controller: maskedController,
style: Styles.textNormalStyle,
maxLines: 1,
),
This solution work for your this specific Question and scenario.
you can achieve using following code.
String formattedPhoneNumber = "(" + phoneNumber.substring(0,3) + ") " +
phoneNumber.substring(3,6) + "-" +phoneNumber.substring(6,phoneNumber.length);
Ricardo pointed to a great library but his answer is half right. Besides the intl_phone_number_input you need to get libphonenumber_plugin installed as well.
intl_phone_number_input: ^0.7.0+2
libphonenumber_plugin:
The method getRegionInfoFromPhoneNumber "discovers" what country the number is from eg +55... it would interpret as it's from Brasil and proceed to format the phone number accordingly. You can also explicitly tell from where the phone number is from passing the country's acronym into the method eg. await PhoneNumber.getRegionInfoFromPhoneNumber(phone, "US"); It'll disregard a country code if it doesn't fit the number you're entering.
String phone = "+19795555555";
PhoneNumber number =
await PhoneNumber.getRegionInfoFromPhoneNumber(phone);
String formattedNumber = await PhoneNumberUtil.formatAsYouType(
number.phoneNumber!,
number.isoCode!,
);
print(formattedNumber); // -> prints: '+1 979-555-5555'
Also you can use: https://pub.dev/packages/intl_phone_number_input/example
String phoneNumber = '+234 500 500 5005';
PhoneNumber number = await PhoneNumber.getRegionInfoFromPhoneNumber(phoneNumber);
String parsableNumber = number.parseNumber();
`controller reference`.text = parsableNumber

How I check if the user is an ADMIN

Hello guys
I'm trying to create a function that allows the user to connect as admin, or simple user by creating a column in the users table called (is_adminn) as INT.
for the moment i'm doing it in a static way :
function _check_admin_login($username, $pword)
{
$target_username="firas";
$target_pass="password";
if(($username==$target_username) && ($pword==$target_pass)){
return TRUE;
}else{
return FALSE;
}
}
and then i will call it in the admin controller :
function username_check($str){
$this->load->module('store_accounts');
$this->load->module('site_security');
$error_msg = "Vous avez saisi un nom d'utilisateur ou un mot de passe incorrecte";
$pword = $this->input->post('pword', TRUE);
$result = $this->site_security->_check_admin_login($str, $pword);
if($result==FALSE){
$this->form_validation->set_message('username_check', $error_msg);
return FALSE;
}else{
return TRUE;
}
}
I did many tests like if the value of is_adminn is equal to 1 , it returns True
function _check_admin_login($username, $pword)
{
$this->load->module('store_accounts');
$this->store_accounts->fetch_data_from_db();
$is_adminn = $data['is_adminn'];
if($is_adminn==1){
return TRUE;
}else{
return FALSE;
}
}
It's easy to do what you want, first time check if the username and the password matches and after that check is the user id have the status is_admin 1.
model
public function check_admin($id){
$query = $this->db->get_where('user', array('id' => $id, 'is_admin' => 1 ));
if ($query->num_rows()>0) {
return true;
}else{
return false;
}
}
controller
$data['temp'] = $this->User_model->get_id_by_email($data['login']['email']);
$data['user'] = $this->User_model->check_login($data['login']['email'], $data['login']['password']);
if ($data['user'] && $this->Admin_model->check_admin($data['temp'][0]['id'])) {
$session_data = array(
//what you wanna store in session
);

Leaflet spiderfy onclick on link to open poup

first, sorry for my english...
I am working on a map using openstreetmap and information leaflet and a listing
According to checked "rubrics", I show markers of different structures on the map and the list of its structures under the map
When they click on the title of the list of structures under the map, I open the popup on the map.
My problem is that there are structures with the meme address (same lat and lon), therefore markers overlaps. Markers is clusters. if they click on the map on cluster, that "spiderfy" and i can see several markers. On the contrary when they click on the title of structure under the map, it doesn't show that spiral and the popup
I have found a solution which disable cluster and that no longer indicates that there are multiple markers to the same address. It is a solution which I am not fully satisfied because I'd like that users see that there are several structures/markers to this address
the map is : http://www.ecocitoyen-grenoble.org/joomla/index.php/annuaire ( to test with the last checkbox "Loisirs, espaces naturels" - picto of a man and click on the last structure in the list)
Scripts:
The map:
<script type="text/javascript">
// <![CDATA[
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA'
});
var map = L.map('map', {
center: [45.1666700, 5.7166700],
zoom: 13,
layers: [osm]
});
var markers = L.markerClusterGroup({
//disableClusteringAtZoom: 18
});
// ]]>
</script>
Display markers :
function rech_picto_structure()
{
map.removeLayer(markers);
markers.clearLayers();
var rub1 = '0';
var rub2 = '0';
var rub3 = '0';
var rub4 = '0';
var rub5 = '0';
var rub6 = '0';
var cp_ville = '';
cp_ville = document.getElementById("cp_ville").value;
if (document.getElementById("box_layer_1").checked )
{
rub1 = '1';
}
if (document.getElementById("box_layer_2").checked )
{
rub2 = '1';
}
if (document.getElementById("box_layer_3").checked )
{
rub3 = '1';
}
if (document.getElementById("box_layer_4").checked )
{
rub4 = '1';
}
if (document.getElementById("box_layer_5").checked )
{
rub5 = '1';
}
if (document.getElementById("box_layer_6").checked )
{
rub6 = '1';
}
if (rub1 == '0' && rub2 == '0' && rub3 == '0' && rub4 == '0' && rub5 == '0' && rub6 == '0')
{
document.getElementById('liste_annuaire').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
document.getElementById('picto_structure_div').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
}
else
{
var xhr = getXhr();
// On défini ce qu'on va faire quand on aura la réponse
xhr.onreadystatechange = function()
{
// On ne fait quelque chose que si on a tout reçu et que le serveur est ok
if(xhr.readyState == 4 && xhr.status == 200)
{
var picto = xhr.responseText;
if (picto.length > 3)
{
liste_structure = '';
var tab_picto = [];
markers_all = [];
var addressPoints = picto.split("|");
//alert (addressPoints);
for (var i = 0; i < addressPoints.length; i++) {
var cel = addressPoints[i].split("µ");
tab_picto.push(cel);
}
for (var i = 0; i < tab_picto.length; i++) {
var a = tab_picto[i];
var title = a[2];
var marker = L.marker(new L.LatLng(a[0], a[1]), { title: title }).bindPopup("<div><b>" + a[3] + "</b><br/>" + a[4] + "<br><br>" + a[5] + "<br/></div>");
liste_structure += a[6];
markers_all.push(marker);
}
for (var i in markers_all){
markers.addLayer(markers_all[i]);
}
map.addLayer(markers);
map.fitBounds(markers.getBounds());
if (liste_structure == '')
{
document.getElementById('liste_annuaire').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
document.getElementById('picto_structure_div').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
}
else
{
document.getElementById('liste_annuaire').innerHTML = liste_structure;
document.getElementById('picto_structure_div').innerHTML = tab_picto.length + " structures trouvées";
}
}
else
{
document.getElementById('liste_annuaire').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
document.getElementById('picto_structure_div').innerHTML = "Veuillez choisir une rubrique pour afficher les structures.";
}
}
}
xhr.open("POST","../../admin/annuaire/generer_carte.php",true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send("rub1="+rub1+"&rub2="+rub2+"&rub3="+rub3+"&rub4="+rub4+"&rub5="+rub5+"&rub6="+rub6+"&cp_ville="+cp_ville);
}
}
Open popup on click on the title of the list under the map
function markerFunction(id){
for (var i in markers_all){
var markerID = markers_all[i].options.title;
//alert(markerID);
if (markerID == id){
LatLng = markers_all[i].getLatLng();
//alert(LatLng);
//map.setView([45.19116, 5.7311], 15);
map.setView([LatLng.lat, LatLng.lng], 20);
//markers.spiderfy();
//markers.unspiderfy()
markers_all[i].openPopup();
};
}}
Thx
stephane
If I understand well, you want to open the popup corresponding to the item in the list, but the marker is in a cluster
Providing you put all your markers in an array when you create them, you can remove the marker from the cluster and add it to the map when you want to open the popup
markerCluster.removeLayer(markers[selectedId]);
map.addLayer(markers[selectedId]);
markers[selectedId].openPopup();
Look at the page source of this: http://franceimage.github.io/leaflet/8/?map=46.566414,2.4609375,6&popup=81
In my case, I want to highlight the marker when I have a 'popup' parm in the url