I want to unsubscribe the observable, shall i use the first() operator for unsubscribe?
Example below,
Rx.Observable.interval(100)
.do(x => console.log(x))
.first()
.subscribe(x => x);
Is the above code will do automatic unsubscribe or need to do anything?
The first() operator takes an optional predicate function and emits an error notification when no value matched when the source completed.
It will unsubscribe after whatever emits first. So to answer your question you do not need to do anything. It will unsubscribe.
Angular 2 using RxJS - take(1) vs first()
The example that you have given is unsubscribed automatically after the first value is submitted. Use bellow example
Rx.Observable.interval(100)
.first()
.subscribe(
x => {
console.log(x)
}, err => {
console.log("error")
}, () => {
console.log("Completed");
});
Normally first() operator is used to get the first value of a sequence. I'm not sure whether we can use it for everywhere when we want to unsubscribe.
Related
Here's the problem I'm having with tauri.
'return' shows you the return value I need, and I know for a fact that writing it this way does not work at all.
'pick_file' is called asynchronously, and I know that message passing seems to work, but is there an easier way to get the value I need.
#[tauri::command]
fn open_file() -> String {
dialog::FileDialogBuilder::default()
.add_filter("data", &["json"])
.pick_file(|path_buf| match path_buf {
Some(p) => return format!("{}", p.to_str().unwrap()),
_ => return "".into()
});
}
First, return in a closure returns from the closure and not from the function that contains it.
The more fundamental issue is that you can't return a String from open_file() if you use FileDialogBuilder::pick_file(). According to the documentation, pick_file() is non-blocking and returns immediately without waiting for the user to pick the file. What you can do in the closure is send the file down a channel, and pick it up elsewhere.
I have a few questions (I am new to Dart) w.r.t the code below which I found. What I am trying to achieve:
1) Write more than one line in the brackets for errors. But I get error saying 'set literals were supported upto 2.2....'. It would also be good to know the list of possible errors so I can alert the user accordingly.
2) Increment a counter pertaining to number of documents and keep storing document id's in one variable, by overwriting the last value if more than one document is found. I am trying to check that there should only be one document and take action if counter goes to 2.
void _checkIfAdmin() {
Firestore.instance
.collection('Admin')
.where('Email', isEqualTo: widget._user.email)
.snapshots()
.handleError((error)=>{
//
})
.listen((data) => data.documents.forEach((doc) => gpCounter+=1)); // Store document id?
print('Counter: $gpCounter');
}
Here I am getting printed gpCounter=0 when I know there are two documents in there. I tried adding async/await in the function but it seems the firebase statement does not return any future so I get a warning to use await only for futures.
I will try to address as many issues as I could understand in your question. If you have any other issues, you should probably ask another question.
Set literals: the syntax for anonymous functions is () {} and not () => {}.
() => is a shorthand syntax to return the value of a single expressions and in your case, you are returning a Set in your anonymous functions because {} create Set's (or Map's if you have colons in there).
The solution for this is (error) { ... }.
You print your gpCounter value synchronously, however, you are listening to a Stream.
Because of that, you should move your print statement to your listen function:
.listen(data) {
print('Counter: ${data.documents.length}');
})
I'm wrapping a promise with firebase inside a function and I would like to call it twice, and then do something once the second call is finished. Here is my code to make it easy to understand, I'm using firebase:
this.updateDB('abc');
this.updateDB('cde');
updateDB = (content) => {
firebase.database().ref('something').update(content)
}
If I called the database update just once I could use the 'then.' and the do something, but I have to call this function twice. How can I do something once both function calls finish?
I tried to research the question got more confused.
Would appreciate any guidelines
Thanks in advance
Since .update() can return a promise, you can use Promise.all() with both promises to know when they are both done:
Promise.all(this.updateDB('abc'), this.updateDB('cde')).then(() => {
console.log('both done here');
}).catch(err => {
console.log('an error in one or both updates occurred');
});
updateDB = (content) => {
// return promise
return firebase.database().ref('something').update(content);
}
My ultimate goal is to assign a chunk of database to class based object. To do this I am utilizing promises in typescript with the help of the .then() function to chain them. However I am running into brick walls.
return(this.httpService.post(someurl, somepayload, someheaders)
.toPromise()
.then(response => response.json())
.then(MyCustomClass.function(MyObject)));
However when this code executes the .then(MyCustomClass.function(MyObject)) before it gets the response.json() which is causing issues in my program.
My question is, why are they occurring in that order and is there any way I can force them to execute in sequence?
You're calling MyCustomClass.function(MyObject), and passing the returned value to then(). What you actually want is to pass a function that, when called, will execute MyCustomClass.function(MyObject):
.then(() => {
MyCustomClass.function(MyObject);
}));
I am trying to pass a value in the callback of an async meteor method. "mongoCollections" is global variable
// Async method
let waiter = function(cb) {
setTimeout(() => {
cb(undefined, {data: 'test', other: mongoCollections})
}, 1000);
}
// Meteor method
Meteor.methods({
'getCollections': () => {
let func = Meteor.wrapAsync(waiter);
let res = func();
return res;
}
});
On the client
Meteor.call('getCollections', (err, res) => {
console.log(err, res)
});
The issue is that in its current state the client callback is not fired, no error or anything.
But if I remove the "other: mongoCollections" part of the object then the callback is fired. Why would sending mongoCollections prevent the callback from being fired at all? If there is an error how can I catch it?
My guess is that you are loosing your context between waiter() and the execution of cb(), which means that mongoCollections is undefined in cb(), thus the call fails.
Try to log mongoCollections in the anonymous function that you setTimeout for. It will probably show as undefined.
Or try it like this:
let waiter = function(cb) {
var _mongoCollections = mongoCollections;
setTimeout(() => {
cb(undefined, {data: 'test', other: _mongoCollections})
}, 1000);
}
(which puts mongoCollections in the closure instsead)
Another possibility (based on comment below): Your mongoCollections object is not serializable. You can try it by logging the result of JSON.stringify(mongoCollections). If this fails you have to extract the parts of the object you need, that can be serialized.
There are a number of things that could be happening here, but my guess is that an error is occurring somewhere and the error message is getting swallowed by a handler somewhere deeper.
You probably want to be using Meteor.setTimeout instead of vanilla setTimeout at a minimum. Have a look here: http://docs.meteor.com/api/timers.html#Meteor-setTimeout
Beyond that, I would follow the previous answerer's advice and try to make sure that mongoCollections is as global as you think it is. If the only change between the callback working and not working is the addition of a single symbol, then the culprit is likely that your added symbol is undefined.