fullcube / loopback-ds-calculated-mixin

A mixin to enable calculated (persisted) properties for loopback Models
MIT License
13 stars 3 forks source link

TypeError: Promise.map is not a function #6

Closed toxsick closed 8 years ago

toxsick commented 8 years ago

Hey guys,

I'm getting this error when I try to use the mixin:

loopback-computed-mixin-demo :: (master*) » node .                                                           ~/Coding/tests/loopback-computed-mixin-demo 127 ↵
/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-ds-calculated-mixin/index.js:38
      Promise.map(Object.keys(options.properties), function(property) {
              ^

TypeError: Promise.map is not a function
    at /Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-ds-calculated-mixin/index.js:38:15
    at notifySingleObserver (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:98:22)
    at iterate (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:181:13)
    at Object.async.eachSeries (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:197:9)
    at doNotify (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:95:11)
    at doNotify (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:93:49)
    at doNotify (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:93:49)
    at doNotify (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:93:49)
    at Function.ObserverMixin._notifyBaseObservers (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:116:5)
    at Function.ObserverMixin.notifyObserversOf (/Users/hannes/Coding/tests/loopback-computed-mixin-demo/node_modules/loopback-datasource-juggler/lib/observer.js:91:8)

I used the loopback-computed-mixin-demo as a starting point and changed it to use the loopback-calculated-mixin instead.

Am I missing something here or is this a bug?

cheers Hannes

toxsick commented 8 years ago

Adding var Promise = require('bluebird'); in index.js L5 seems to fix the problem.

Maybe related to Sails Issue 51: TypeError: undefined is not a function (Promise.map) ??

jbcpollak commented 8 years ago

I am having a similar issue with Promise.all. I am using Node 5.7.1, where the ES6 Promise API is fully implemented. I think something is playing with the global Promise object, because Promise.all works fine in test code that doesn't require loopback. For example:

var fulfills = Promise.all([
    new Promise(function(resolve)   { setTimeout(resolve,200,"foo"); }),
    new Promise(function(resolve)   { setTimeout(resolve,100,"bar"); }),
]).then(values => {
    console.log(values)
});

Works fine by itself (drop it into test.js and run node test.js), but when you put it into a model's remote method, you get this:

Promise.all is not a function
    at Function.all (native)
isonet commented 8 years ago

I have the same problem as @toxsick and his solution worked for me. I created a pull request to fix this: #9

mrfelton commented 8 years ago

Thanks @isonet . Have merged your patch.

pulkitsinghal commented 7 years ago

@mrfelton - I want to share a recent experience on the same topic with you. I hope you'll forgive the minor thread hijack. Feel free to point me elsewhere but I think most people using google will end up here because this issue has all the right keywords.

In a nodejs project, we moved:

and I suspect that anything past node-v4 treats the following global.Promise = require('bluebird'); in a different fashion. I wish I could find the relevant nodejs docs/discussion to confirm/deny this.

Loopback at least doesn't have any red flags in its changelog

@jbcpollak After moving to 2.37.1 with node-v6 my colleague @Mohammed-Aadil noticed:

the code outside any of our models' export function would use global.Promise but the code inside export function would use node-v6's native Promise implementation

I am left wondering if this is a node-v6 desired behaviour or something that occurs by mixing loopback with certain version of nodejs ... If I or my team narrows this down by trial & error then we'll share otherwise please treat this comment as one more signpost on the journey.

So yes, var Promise = require('bluebird'); is an appropriate workaround and maybe even the right approach and not "just" a workaround ... but still I worry because I wonder if this ( global.Promise = require('bluebird'); ) is still the right way to inform the overall loopback framework about which promise implementation to use? Not expecting an answer, only voicing something that maybe in the back of our collective minds.

cc @kamal0808 @aquid

mrfelton commented 7 years ago

@pulkitsinghal we have found something similar.

By setting global.Promise = require('bluebird'); at the top of your server.js file, you can get loopback to use bluebird for it's promises (with loopback 3.x this is no longer needed as it's the default behaviour). But, in order to use Bluebird for new Promises that we create within a model customisation file we always need to explicitly const Promise = require('bluebird') at the top of those files. I'm unsure of the reason for this although I haven't spent a lot of time investigating.