I'm quite new at rxjs stuff so please be patience :).
var source = Rx.Observable.fromEvent(document, 'keyup');
source.filter(function(x){
console.log('filter with', x);
return true;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: keyup!',x.keyCode);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
whats the right way to debug inside filter
I dont see any filter with
in the console
I've also tried with
var source = Rx.Observable.fromEvent(document, 'keyup');
source.filter(function(x){
console.log('filter with', x);
return true;
});
source.do(x => console.log('do with',x));
var subscription = source.subscribe(
function (x) {
console.log('Next: keyup!',x.keyCode);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
with no lucky
Can you give me an hint please ?
source.filter() is creating a new Observable, yet you only subscribe to the original Observable, source. Observables that aren't subscribed to are not carried out
You have to do something like this:
source.filter()
.do()
.subscribe()
Related
I have tried to insert the value in db in my mocha test i am getting this error i tried few of the following ways but nothing work out.
var assert=require('chai').assert;
const user=require('../model/user')
i tried both way
describe('insertDataLasone',()=>{
it('should save the value ',(done)=>{
var User = new user({fname:'test'});
User.save().then(done=>{
done()
}).catch(done=>done())
})
})
describe('User', function() {
describe('#save()', function() {
// this.timeout(5000)
it('should save without error', function(done) {
var User5 = new user({fname:'test'});
User5.save(function(done) {
if (err) done(err);
else setTimeout(done,3000);
});
});
});
});
This error occurs when done() is not called in a test. Make sure you are calling done().
var assert = require('chai').assert;
const User = require('../model/user');
describe('insertDataLasone', () => {
it('should save the value ', done => {
var user = new User({ fname: 'test' });
user.save().then(() => {
done();
})
.catch(done); // mocha done accepts Error instance
});
});
or
var assert = require('chai').assert;
const User = require('../model/user');
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user5 = new User({ fname: 'test' });
user5.save(function(err) {
if (err) done(err);
else done();
});
});
});
});
Read https://mochajs.org/#asynchronous-code carefully
I have a forEach loop that processes data in an array. Somewhere in the middle of that loop I have to wait for a change in a DOM element, grab that change, process it, and only then can I continue processing the array.
I'm hoping to see this in console:
Preparing "aaa"
Waiting for result on "aaa"
Processing result on "aaa": <random number>
Got result for "aaa": <random number>something`
And the same thing for each element in stuffToProcess array in the code snippet below. It's a simplified example of the code.
I realize similar questions have been asked and answered countless times before, but after reading through many of them, and trying many different things for hours, I still can't figure this one out.
function dummy() {
$('#trackMe').text(Math.random());
}
async function doWork(stuffToProcess) {
let target = $('#trackMe')[0];
let config = { attributes: true, childList: true, characterData: true, values: true };
let observer = new MutationObserver(function(mutations,item) {
console.log('Processing result on "%s": %s', item, target.innerText);
item = item + 'something';
return new Promise(resolve => {
resolve(item);
});
});
observer.observe(target, config);
stuffToProcess.forEach(async function(item) {
console.log('Preparing "%s"', item);
console.log('Waiting for result on "%s"', item);
let change = await observer(item);
//^^^ this needs to "await" for data from observer before the loop continues
console.log('Got result for "%s": %s', item, change);
});
//observer.disconnect();
}
doWork(['aaa', 'bbb', 'ccc']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="trackMe">No changes yet</p>
<button onclick="dummy()">Click me to change</button>
Well, I managed to solve it somehow. Probably not the cleanest solution though, so if anyone recommends any improvements on this, I'll happily edit the solution / upvote your answer.
function dummy() {
$('#trackMe').text(Math.random());
}
async function doWork(stuffToProcess) {
let target = $('#trackMe')[0];
let config = {
attributes: true,
childList: true,
characterData: true,
values: true
};
let observer;
function isItDone(item) {
return new Promise(resolve => {
observer = new MutationObserver(function(mutations) {
console.log('Processing result on "%s": %s', item, target.innerText);
result = target.innerText + 'something';
resolve(result);
});
observer.observe(target, config);
});
}
for (index in stuffToProcess) {
console.log('Preparing "%s"', stuffToProcess[index]);
console.log('Waiting for result on "%s"', stuffToProcess[index]);
let change = await isItDone(stuffToProcess[index]);
observer.disconnect();
console.log('Got result for "%s": %s', stuffToProcess[index], change);
}
}
doWork(['aaa', 'bbb', 'ccc']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="trackMe">No changes yet</p>
<button onclick="dummy()">Click me to change</button>
Here is an example using only JavaScript, I hope it helps you.
function getData() {
return new Promise(function(resolve, reject) {
// resolve();
// reject();
});
}
function example1() {
// code ...
async function getAsyncData() {
let data = await getData();
console.log(data);
// code ...
}
let element = document.getElementById(...);
let observer = new MutationObserver(function(mutations) {
getAsyncData();
});
let config = {attributes: true, childList: true, characterData: true};
observer.observe(element, config);
// code ...
}
document API here http://bluebirdjs.com/docs/api/cancellation.html
i try it in my demo,but doesn't work
var Promise = require('bluebird');
var a = require('./a');
var b = require('./b');
var cancelPromise = Promise.resolve();
cancelPromise.cancel();
cancelPromise = a.fnA()
.then(function() {
return b.fnB();
})
.then(function() {
console.log('done');
})
.finally(function() {
if (cancelPromise.isCancelled()) {
console.log('canceled');
}
console.log('end');
});
so how to use this method?
To use .cancel(), first you need to turn cancellation ON and only then call function .cancel()
If your work with bluebird below 3, your code should look something like that:
var mainAction = a.fnA()
.cancellable() // => cancellation turned on
.then(function() {
return b.fnB();
})
.then(function() {
console.log('done');
})
.catch(function( err ){ // => 'Reason for cancel'
console.error(err);
})
.finally(function() {
console.log('end');
});
mainAction.cancel('Reason for cancel');
And if you work with bluebird 3 and above, the code should look like this:
var successfulFetch = false, mainAction = a.fnA()
.then(function() {
return b.fnB();
})
.then(function() {
console.log('done');
}).finally(function() {
if(!successfulFetch){
console.error('Reason for cancel');
}
console.log('end');
});
mainAction.cancel();
Also I suggest you to take a look at this post: Cancel a delayed Bluebird promise
which was really helpful for me, when I had a similar problem
I need to iterate over result set from the sequelize result. I have a code that works, but I think something is wrong with it, and it should not be done this way.
I have a feeling this is a blocking code.
This is the code that works:
models.Project.findAll({
where: {ProjectId: projectId}
})
.then(function (projects) {
//Iteration is here
var projectList = [];
projects.forEach(function (res) {
projectList.push(res.dataValues.PartId);
});
//then bulk lookup for the result
models.Customers.findAll({
where: {'id': {in: [projectList]}}
}).then(function (customers) {
reply(customers).code(200);
}, function (rejectedPromiseError) {
reply(rejectedPromiseError).code(401);
});
//reply(sameparts).code(200);
}, function (rejectedPromiseError) {
reply(rejectedPromiseError).code(401);
});
This iteration parts is done:
projects.forEach(function (res) {
projectList.push(res.dataValues.PartId);
});
And then this code is executed as another query:
models.Customers.findAll({
where: {'id': {in: [projectList]}}
}).then(function (customers) {
reply(customers).code(200);
}, function (rejectedPromiseError) {
reply(rejectedPromiseError).code(401);
});
How can I rearange it so it uses Promises?
EDIT (Possible solution):
After playing a bit, I believe I have implemented promises.
getAll: function (request, reply) {
var projectId = request.params.projectid;
var promises = [];
var post;
models.SamePart.findAll({
where: {ProjectId: projectId}
})
.then(function (sameparts) {
//Iteration is here
sameparts.forEach(function (res) {
promises.push(
Promise.all([
models.Parts.findAll({where: {id: res.dataValues.PartId}})
]))
});
//Bulk lookup for the parts that were marked as identical
return Promise.all(promises);
}).then(function (completepartslist) {
reply(completepartslist).code(200);
});
Is this a correct approach? It seems that completepartslist contains many unwanted objects, including Promise stuff. How can I flatten it, so to avoid complex for loops?
If you are using .then(), then you are, in all probability, already using promises.
Your original, working code doesn't appear to be blocking.
Your final getAll() looks like it should simplify to :
getAll: function (request, reply) {
models.SamePart.findAll({
where: { ProjectId: request.params.projectid }
}).then(function (sameparts) {
return Promise.all(sameparts.map(function (res) {
return models.Parts.findAll({ where: { id: res.dataValues.PartId } });
}));
}).then(function (completepartslist) {
reply(completepartslist).code(200);
});
}
However, you need to add error handling back in.
even more simplified
getAll: function (request, reply) {
models.SamePart.findAll({
where: { ProjectId: request.params.projectid }
}).reduce(function (completepartslist, sameparts) {
return models.Parts.findAll({ where: { id: sameparts.PartId } }).
then(function(res){
completepartslist.concat(res)
});
}), []);
}).then(function (completepartslist) {
reply(completepartslist).code(200);
});
}
I'm trying to fill some local data resolving a series of remote calls.
When every promise is resolved, I load the data and proceed.
The method $q.all( [] ) does exactly this:
$q.all([
this.getUserInfo(11)
.then(function (r) {
results.push(r)
}),
this.getUserConns()
.then(function (r) {
results.push(r)
}),
this.getUserCtxs()
.then(function (r) {
results.push(r)
})
])
.then(function () {
console.log(results)
})
Problem is, this code is not resilient.
If any of these call fails, nobody gets the fish!
Wrapping the calls in a try/catch statement, simply causes $q.all() to entirely ignore the entry, even when not failing (note the console.log in the func)...
$q.all([
this.getUserInfo2(11)
.then(function (r) {
results.push(r)
}),
function () {
try {
this.getUserGroups()
.then(function (r) {
console.log(r)
results.push(r)
})
}
catch (err) {
console.log(err)
}
},
])
.then(function () {
console.log(results)
})
Output:
[Object]
Any hint on how I could wrap this to be resilient?
Thanks to #dtabuenc, I've gone one step further.
Implementing the error callback, I can avoid the breaking of the chain, and push the values of the resolved promises.
However, a nasty Exception is still displayed on the console...
How can I get rid of that if I cannot try/catch on async requests?
Caller code
return $q.all([
this.getUserInfo(user_id)
.then(function (r) {
results['personal_details'] = r
}),
this.getUserConns()
.then(
function (r) {
results['connections'] = r
},
function(err) {
console.log(err)
})
])
.then(function () {
return (results)
})
Callee code (inject with an exception)
getUserConns: function() {
return __doCall( ws.getUserConnections, {} )
.then( function(r) {
// very generic exception injected
throw new Error
if (r && r.data['return_code'] === 0) {
return r.data['entries']
}
else {
console.log('unable to retrieve the activity - err: '+r.data['return_code'])
return null
}
})
},
This will work but also push the errors to the array.
function push(r) {
results.push(r);
}
$q.all([
this.getUserInfo(11).then(push).catch(push),
this.getUserConns().then(push).catch(push),
this.getUserCtxs().then(push).catch(push)
])
.then(function () {
console.log(results);
})
You should also improve your understanding of promises, you never should use try-catch with promises - when using promises, you use the .catch() method (with everything else being implicitly a try). This works for normal errors as well as asynchronous errors.
If you want to totally ignore the errors:
function push(r) {
results.push(r);
}
function noop() {}
$q.all([
this.getUserInfo(11).then(push).catch(noop),
this.getUserConns().then(push).catch(noop),
this.getUserCtxs().then(push).catch(noop)
])
.then(function () {
console.log(results);
})
I think it's easier to do :
$q.all([
mypromise1.$promise.catch(angular.noop),
mypromise2.$promise.catch(angular.noop),
mypromise1.$promise.catch(angular.noop)
])
.then(function success(data) {
//.....
});
I'm not sure what you mean by resilient. What do you want to happen if one of the promises fails?
Your try-catch won't work because the promise will fail asynchronously.
You can however pass in an error handler as the second parameter to the then() call and do whatever you wish there.
Same issue here. For those of you with for loops: inside a then response:
var tracks = [];
var trackDfds = [];
for(var i = 0; i < res.items.length; i++){
var fn = function () {
var promise = API.tracks(userId, res.items[i].id);
return promise.then(function (res) {
if (res.items.length) {
tracks.push(res.items);
}
}).catch(angular.noop);
};
trackDfds.push(fn());
}
$q.all(trackDfds)
.then(function (res) {
console.log(tracks);
});
#Esailija's answer seems like a workaround to a problem.
You can't resolve the problem outside the main contributor to the problem: $q.
It seems a bit wiser to have reject callbacks for each then (2nd argument) and in there to insert $q.reject(...).
Example:
$q.all([
this.getUserInfo(11).then(
function (response) { // UI data preparation for this part of the screen },
function (response) {
$q.reject(response);
}
),
// ...
])
.then(
function () {
// all good
},
function () {
// at least one failed
}
)
This is particularly indicated when the UI model depends on all ajax calls.
Personally I think this is the safe way to proceed anyway, because most of the times you do want to push some server messages to some toast component on the reject callbacks, or alert the user in some way (queuing 7 ajax calls doesn't mean you can't show anything because 1 failed - it means you won't be able to show some region of the screen - that needs a specialized feedback to the user).