Return value of updateEmail() - firebase - firebase

I want to check if updateEmail() goes through or not. If it changes an email or not and I don't know what is the return value of that function so I can check it.
I tried something like this
if(user.updateEmail(email) != null) {
msg = "Success";
}
And I am never getting a null value if it is good or not.

The return values of the User.updateEmail method is Future<void>. So while the future has no resulting value, you can check whether it succeeded or failed by checking the result of the future itself. From there, it looks like it should be something like this:
user.updateEmail(email).then(() {
msg = "Success";
})
.catchError(handleError);

Related

How to get data from firebase query based on value from another firebase query in FutureBuilder in Flutter?

I am new to flutter and I am sure there is a simple way of doing this. Let me first give you a background. I have 2 tables(collections). The first one store a mapping. Therefore it returns a key based on an id which will be used to query the second table and retrieve the data from firebase.
I have written 2 data models and 2 functions which return Future<> data. They are as follows-
Future<SpecificDevice> getSpecificDevice(String deviceId) {
Future<SpecificDevice> obj =_database.reference().child("deviceMapping").orderByChild("deviceId").equalTo(deviceId).once().then((snapshot) {
SpecificDevice specificDevice = new SpecificDevice(deviceId, "XXXX", new List<String> ());
if(snapshot.value.isNotEmpty){
print(snapshot.value);
snapshot.value.forEach((key,values) {
if(values["deviceId"] == deviceId) {
specificDevice.deviceKey = values["deviceDesc"];
specificDevice.vendorList = List.from(values["vendorList"]);
}
});
}
return specificDevice;
});
return obj;
}
This function gets the mapping deviceId -> deviceKey.
This is the key of record stored in another table. Following is the function for it.
Future<Device> getDeviceDescription(String deviceKey) {
Future<Device> device = _database.reference().child("deviceDescription").once().then((snapshot) {
Device deviceObj = new Device("YYYY", "YYYY", "YYY", "YYYY", "YYYY");
if(snapshot.value.isNotEmpty){
print(snapshot.value);
//Future<SpecificDevice> obj = getSpecificDevice(deviceId);
//obj.then((value) {
snapshot.value.forEach((key,values) {
if(key == deviceKey) { // compare with value.deviceKey instead
print(values["deviceDescription"]); // I get the correct data here.
deviceObj.manual = values["deviceManual"];
deviceObj.deviceType = values["deviceType"];
deviceObj.description = values["deviceDescription"];
deviceObj.brand = values["deviceBrand"];
deviceObj.picture = values["devicePicture"];
}
// });
});
}
return deviceObj;
});
return device;
}
Now both of these functions work. I want to make it work one after the other. In the above function, if I uncomment the lines of code, the data is retrieved properly in the inner function but it returns initial default values set because the values get returned before setting the obj of SpecificDevice.
Here is where I am getting the error. I am calling the second function in FutureBuilder<> code with the above lines uncommented and taking input param as deviceId.
return FutureBuilder<Device>(
future: getDeviceDescription(deviceId),
builder:(BuildContext context,AsyncSnapshot snapshot){... // using snapshot.data in its child.
Here in snapshot.data. would give me YYYY. But it should get me the value from the database.
I am stuck with this for a while. Any help in fixing this? or if what I am trying to do is clear then please suggest me a better way to approach this. Thanks in advance!
The answer is rather simple:
first and foremost - you forgot to use async / await keywords, which will guarantee synchronous data retrieval from the database. Always use them, if you are connecting to any network service
to make one command work after another - use .then((value) {}). It will get data from the first function (which you pass using return) and use it in the second function.
Solved the problem by changing the calling function to -
return FutureBuilder<Device>(
future: getSpecificDevice(deviceId).then((value){
return getDeviceDescription(value.deviceKey);
}),
builder:(BuildContext context,AsyncSnapshot snapshot){

How do I determine, if Observable has never received anything?

How do I determine, if the Observable is "empty"?
Better, that it has never received anything.
My code looks like this:
spots: Observable<Spot[]>;
And I've tried several things I found on Google like:
spots.isEmpty();
spots.length;
spots.length();
spots().length;
spots.first();
But none of them works like I want..
I need this functionality, to fill a list in Ionic2 with No items found until the first item is loaded.
This is how I solve it in my code:
if ( arrayOfItems && arrayOfItems.length > 0 ) {
// display the list
return arrayOfItems.map((item) => { return item; })
} else {
// show a message that nothing was found
return "Nothing to see here...";
}
This will check that the variable has some sort of positive value (ie. it is not null, false or undefined) and that the array has at least one value. If that is not the case then display a message that nothing was found.
I solved it like this:
I have an variable let isEmpty=true; and set it to false when I receive the first Object in the Observable:
spots.subscribe(() => {
this.empty = false;
...
});

meteor if document exists return true/false

How can I determine if a document exists within a collection in Meteor?
Edited: New code.
the mongodb has a document with the ProductName: Apples
the inputproduct is "Apples"
var exists = Products.find({ProductName: inputproduct});
if(exists)
{
alert("it exists");
}else{
alert('doesnt exist');
}
all I get back is : "it exists" regardless of the value of inputproduct. I have output what inputproduct is and it comes back "Apples" no problem. Not sure what is going on here. Tried it several ways using find or findOne and nothing.
You almost had it. However, meteor's collection.findOne will return the first object which matched, or undefined (which is falsy) if no match was found. Try this:
var exists = Products.findOne(selector, projection);
if(exists)
{
do something...
}

Complex operation with BaconJS (FRP)

I'm trying to do this relatively complex operation in BaconJs.
Basically, the idea is keep trying each check until you have a 'pass' status or they all fail. The catch is that 'pending' statuses have a list of Observables (built from jquery ajax requests) that will resolve the check. For performance reasons, you need to try each Observable in order until either they all pass or one fails.
Here's the full pseudo algorithm:
Go thru each check. A check contains an id and status = fail/pass/pending. If pending, it contains a list of observables.
If status = pass, then return the id (you're done!)
if status = fail, then try the next check
if status = pending
try each observable in order
if observable result is 'false', then try the next check
if reach end of observable list and result is 'true', then return the id (you're done!)
Here's the Bacon code. It doesn't work when the Observables are Ajax requests.
Basically, what happens is that it skips over pending checks....it doesn't wait for the ajax calls to return. If I put a log() right before the filter(), it doesn't log pending requests:
Bacon.fromArray(checks)
.flatMap(function(check) {
return check.status === 'pass' ? check.id :
check.status === 'fail' ? null :
Bacon.fromArray(check.observables)
.flatMap(function(obs) { return obs; })
.takeWhile(function(obsResult) { return obsResult; })
.last()
.map(function(obsResult) { return obsResult ? check.id : null; });
})
.filter(function(contextId) { return contextId !== null; })
.first();
UPDATE: the code works when the checks look like this: [fail, fail, pending]. But it doesn't work when the checks look like this: [fail, pending, pass]
I am more familiar with RxJS than Bacon, but I would say the reason you aren't seeing the desired behavior is because flatMap waits for no man.
It passes [fail, pending, pass] in quick succession, fail returns null and is filtered out. pending kicks off an observable, and then receives pass which immediately returns check.id (Bacon may be different, but in RxJS flatMap won't accept a single value return). The check.id goes through filter and hits first at which point it completes and it just cancels the subscription to the ajax request.
A quick fix would probably be to use concatMap rather than flatMap.
In RxJS though I would refactor this to be (Disclaimer untested):
Rx.Observable.fromArray(checks)
//Process each check in order
.concatMap(function(check) {
var sources = {
//If we pass then we are done
'pass' : Rx.Observable.just({id : check.id, done : true}),
//If we fail keep trying
'fail' : Rx.Observable.just({done : false}),
'pending' : Rx.Observable.defer(function(){ return check.observables;})
.concatAll()
.every()
.map(function(x) {
return x ? {done : true, id : check.id} :
{done : false};
})
};
return Rx.Observable.case(function() { return check.status; }, sources);
})
//Take the first value that is done
.first(function(x) { return x.done; })
.pluck('id');
What the above does is:
Concatenate all of the checks
Use the case operator to propagate instead of nested ternaries.
Fail or pass fast
If pending create a flattened observable out of check.observables, if they are all true then we are done, otherwise continue to the next one
Use the predicate value of first to get the first value returned that is done
[Optionally] strip out the value that we care about.
I agree with #paulpdaniels Rx-based answer. The problem seems to be that when using flatMap, Bacon.js won't wait for your first "check-stream" to complete before launching a new one. Just replace flatMap with flatMapConcat.
Thanks to #raimohanska and #paulpdaniels. The answer is to use #flatMapConcat. This turns what is basically a list of async calls done in parallel into a sequence of calls done in order (and note that the last "check" is programmed to always pass so that this always outputs something):
Bacon.fromArray(checks)
.flatMapConcat(function(check) {
var result = check();
switch(result.status) {
case 'pass' :
case 'fail' :
return result;
case 'pending' :
return Bacon.fromArray(result.observables)
.flatMapConcat(function(obs) { return obs; })
.takeWhile(function(obsResult) { return obsResult.result; })
.last()
.map(function (obsResult) { return obsResult ? {id: result.id, status: 'pass'} : {status: 'fail'}; });
}
})
.filter(function(result) { return result.status === 'pass'; })
.first()
.map('.id');

How can i know specific value on a form using `request.form`?

How can i know specific value on a form using request.form?
I am trying it long but no success.
i want to check something like this
if (request.form.contains("text_check")) //But it doesn't work
{
go in;
}
else{
here we go;
}
i want to know specific value from AllKeys, and total count of all keys too.
To check if a key exists in the form data, you can simply compare the value to null:
if (Request.Form["text_check"] != null) {
If the key exists, you always get a string value back, even if the value is empty.
If you want to check if there is a non-empty value, you can use the String.IsNullOrEmpty method:
if (!String.IsNullOrEmpty(Request.Form["text_check"])) {
If you want to check if a certain key exists in the Request.Form collection you can do so like this:
if(Request.Form.AllKeys.Any(k => k == "text_check")) { ... }
and to then get it's value:
if(Request.Form.AllKeys.Any(k => k == "text_check"))
{
var textCheckValue = Request.Form["text_check"];
}
To get the total number of keys then:
var count = Request.Form.AllKeys.Count();
If you are using server side controls, you can use Request.Form.Contains(text_check.UniqueId) to make sure form is having that value during postback.

Resources