Comments (25)
This isn't really related to couch potato.
If you are responding to non-Angular events and you want Angular to know about it (usually you do), then wrap your event handler code in $rootScope.$apply(function () { /* your code here */ });
Couch potato, like the rest of the angular components in your app, will then be "in the loop" as to what happens in your event handler.
I'll close this since it isn't really a couch potato issue. If you feel like there is a couch potato aspect to this that I'm missing, please feel free to respond.
EDIT: I should have been a bit more thorough -- if the event you're talking about takes place within the context of a specific view, you can use the $scope associated with that view rather than $rootScope.... basically the gist of it is that whatever scope should be applicable to the event is the one that should know about it. $rootScope if its a global-scoped event, and the $scope of the view if the component is some UI widget in a particular view...
from angular-couch-potato.
I'm not sure I understand. BTW, this isn't really an issue, just a question. In your examples you have a bunch of states, which have resolve: {dummy:blahblah}. I don't want the state to resolve until after the vendor library has run it's script loading (at which time the 'mp_ready' event is fired). Wouldn't this go inside the resolve:{}?
from angular-couch-potato.
Ah, ok. Still not technically a couch potato issue, but at least now I understand your question a bit better.
It seems you'd want the function that you give to the resolve property to return a promise that is resolved by the event handler for the event you specified above. This means that you set up the promise, you return it, and then you hang on to the deferred object so that the event handler can call deferred.resolve().
Because the promise will be hanging unresolved until the event occurs, the resolution process will pause while it waits for that event. Once the event fires, the handler should call resolve on the deferred object, thus resolving the promise, and things move forward.
from angular-couch-potato.
That's exactly right. Before I switched from routes to states, I had the following, in my route config:
resolve: {
load: ['$q', '$rootScope', function ($q, $rootScope) {
var deferred = $q.defer();
require([
'someFile',
'anotherFile',
], function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}]
}
Is there an example of how I could accomplish this same thing using ui-router and couch potato?
from angular-couch-potato.
BTW, I realize that this isn't a couch potato question, but more of a ui-router/angular question. I apologize for that.
from angular-couch-potato.
I think you may want to use two resolve properties -- one that deals with loading the components you need via couch potato, and another that handles the promise related to the event you're trying to wait for...
Alternatively, if one of the couch potato components you're waiting for depends on the external event happening before it can be considered initialized, then you'd probably shift the burden of listening for the event into the defining module itself (i.e. the require.js module that defines the couch potato component which depends on the event from the external lib).
EDIT: there might be an issue with that alternative, in that require.js doesn't want to wait for promises and wouldn't hold up for an external event either.... so probably the former idea is better than the latter.
from angular-couch-potato.
If you want to combine waiting for your components with waiting for the external event into one resolve function, it might look something like:
resolve: {
load: ['$q', '$rootScope', function ($q, $rootScope) {
var overallDeferred = $q.defer();
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
$q.all([eventDeferred.promise, requireDeferred.promise])
.then(overallDeferred.resolve);
require([
'someFile',
'anotherFile',
], function () {
$rootScope.$apply(requireDeferred.resolve);
});
document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return overallDeferred.promise;
}]
}
Note: edited since first posted to reflect that it's the promises that are passed to $q.all, not the deferred objects.
from angular-couch-potato.
Great, thanks for that. That might work in ngRoute but I'm using ui.router/scs.couch-potato and resolveDependencies(). Would it work the same way?
from angular-couch-potato.
That might look something like:
resolve: {
load: ['$q', '$rootScope', '$couchPotato', function (
$q, $rootScope, $couchPotato
) {
var overallDeferred = $q.defer();
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
$q.all([eventDeferred.promise, requireDeferred.promise])
.then(overallDeferred.resolve);
$couchPotato.resolveDependencies(['someFile', 'anotherFile'])
.then(requireDeferred.resolve);
document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return overallDeferred.promise;
}]
}
from angular-couch-potato.
It's weird, I'm tweaking what you have above, but resolveDependencies() never gets called on couch potato.. I'm trying to figure out why.
from angular-couch-potato.
Ok, resolveDependencies() does get called, however, the requireDeferred never gets resolved, and I can't log anything after that..
from angular-couch-potato.
You can put a breakpoint in your browser around here: https://github.com/stu-salsbury/angular-couch-potato/blob/master/src/couchPotato.js#L166 to figure out what's happening. If it's being called but it's not resolving its promise then something may be erroring out. In looking at the code, I can see that it probably should have a try/catch in it that rejects the promise on catch. Since it's not there, you may find that an error is happening, causing the promise to just die on the vine.
from angular-couch-potato.
If an error is your problem, you could at least get better notification if you change the couch potato function to look like this (untested):
function resolveDependencies(dependencies, returnIndex, returnSubId) {
function delay($q, $rootScope) {
var defer = $q.defer();
try {
require(dependencies, function() {
var args = Array.prototype.slice(arguments);
var out;
if (returnIndex === undefined) {
out = arguments[arguments.length - 1];
}
else {
argForOut = arguments[returnIndex];
if (returnSubId === undefined) {
out = argForOut;
}
else {
out = argForOut[returnSubId];
}
}
defer.resolve(out);
$rootScope.$apply();
});
}
catch (err) {
defer.reject(err);
}
return defer.promise;
}
delay.$inject = ['$q', '$rootScope'];
return delay;
}
.... I'd deal with this myself, but I'm kinda busy ATM...
from angular-couch-potato.
I think we're back in couch potato territory, so I'm reopening.... :)
from angular-couch-potato.
It's funny, I tried that before your post. I put one at 165 and 162 and neither of them are being hit. I will keep digging.
from angular-couch-potato.
If they aren't being hit, but resolveDependencies is being hit, then there must be an issue with calling it from the service $couchPotato as opposed to the provider $couchPotatoProvider.
If you're working from the sample code, you probably already injected $couchPotatoProvider at the same time you injected $stateProvider, so it should be available through closure.... this isn't necessarily a kosher way to go, but given what seems like a couch potato bug I'd recommend it for now (adapt as needed):
resolve: {
load: ['$q', '$rootScope', function (
$q, $rootScope
) {
var overallDeferred = $q.defer();
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
$q.all([eventDeferred.promise, requireDeferred.promise])
.then(overallDeferred.resolve);
// $couchPotatoProvider is still available due to JS closure from above
$couchPotatoProvider.resolveDependencies(['someFile', 'anotherFile'])
.then(requireDeferred.resolve);
document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return overallDeferred.promise;
}]
}
Does that help?
from angular-couch-potato.
A note, if I remove '.then(requireDeferred.resolve);' after resolveDependencies(), any code after that line executes. If I leave it in there, nothing executes after it. Might be interesting.
Also, breakpoint at 190 DOES get hit, but breakpoints at 162 and 165 do not get hit.
I will experiment with your previous comment. Thanks!
from angular-couch-potato.
btw, when I say "not kosher" I mean that I lose style points for making this the only way to use the resolveDependencies function, not that your code suffers. The same code is doing the registering one way or the other, I just shouldn't be forcing you to use closure to maintain a reference to the provider.
from angular-couch-potato.
Hmmmm....
if I remove '.then(requireDeferred.resolve);' after resolveDependencies(), any code after that line executes. If I leave it in there, nothing executes after it.
makes me wonder if you're resolve function is the one throwing an unhandled error. You might also want a try/catch of your own...
from angular-couch-potato.
Haha.. It's been a while since I looked at this code. I notice that there is an inner function that is returned by resolveDependencies (named internally as "delay").... which is all well and good when you're setting up your resolve property at config time (as is the case in the sample) since what's left after calling it is a function that itself does the run-time work.
Not so good if all of your code is running at Angular run time. Forget the stuff about switching between the provider and the service.... try this (call the function returned by resolveDependencies):
resolve: {
load: ['$q', '$rootScope', '$couchPotato', function (
$q, $rootScope, $couchPotato
) {
var overallDeferred = $q.defer();
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
$q.all([eventDeferred.promise, requireDeferred.promise])
.then(overallDeferred.resolve);
var resolveFunc = $couchPotato.resolveDependencies(['someFile', 'anotherFile']);
resolveFunc().then(requireDeferred.resolve);
document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return overallDeferred.promise;
}]
}
from angular-couch-potato.
(the bug is that if called at run-time, the inner function should be executed right away without you having to do it -- the workaround above should get you past that for now)
from angular-couch-potato.
Ahh, I see what you mean. The problem with that, is now $q and $rootScope are undefined in delay()
from angular-couch-potato.
(Coincidentally or not) I think you happen to have them already! :)
How about:
resolve: {
load: ['$q', '$rootScope', '$couchPotato', function (
$q, $rootScope, $couchPotato
) {
var overallDeferred = $q.defer();
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
$q.all([eventDeferred.promise, requireDeferred.promise])
.then(overallDeferred.resolve);
var resolveFunc = $couchPotato.resolveDependencies(['someFile', 'anotherFile']);
resolveFunc($q, $rootScope)
.then(requireDeferred.resolve);
document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return overallDeferred.promise;
}]
}
from angular-couch-potato.
YES!! You rock! Finally got this to work, I tweaked your solution just a hair, using $q.all(), do you see any issues in doing so?
resolve: {
load: ['$q', '$rootScope', '$document', '$couchPotato', function ($q, $rootScope, $document, $couchPotato) {
var eventDeferred = $q.defer();
var requireDeferred = $q.defer();
var promises = [requireDeferred.promise, eventDeferred.promise];
var resolveFunc = $couchPotato.resolveDependencies([
'someFile',
'anotherFile'
]);
resolveFunc($q, $rootScope).then(requireDeferred.resolve);
$document.on('mp_ready', function () {
$rootScope.$apply(eventDeferred.resolve);
});
return $q.all(promises);
}]
},
from angular-couch-potato.
Nope: 6 of one, half-dozen of the other. $q.all returns the promise you care about so that should work. Yours is cleaner. 👍
from angular-couch-potato.
Related Issues (20)
- testing HOT 22
- test issue
- Add http interceptor factory HOT 1
- document registerConstant support HOT 4
- Lazy loaded directive is not applied on the controller's view HOT 1
- Example of ad-hoc module loading HOT 5
- how to lazy load a controller whose name has a variable from the $stateParams in resolve's dummy?
- Add minify js file
- ready doesn't fire in angular 1.0.7? HOT 5
- super lazy : both html and js HOT 1
- Whether to support cmd?
- Add support for registerComponent
- sample ui-router example code is not work HOT 1
- Angular route with html5Mode giving 'Not found' page after reload in apache HOT 9
- AngularUI Router HOT 1
- where is server.js? HOT 1
- What about the documentation? HOT 2
- How to load the Main Controller? HOT 4
- Guidance on how to get Directives in HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular-couch-potato.