Comments (18)
In what browser did you have the issue?
I wasn't able to reproduce it in Chrome 40 and IE11.
from angular-aop.
Chrome 40.0.2214.111.
Porting over the fully generated typescript code over to plnkr, and the error is generating. My guess is it's something to do with typescripts anonymous wrapping.
from angular-aop.
There are dependencies which do not exist:
// ...
angular.module("my_app", [
"uuid4",
"ngTouch",
"AngularAOP"
]).factory("log_aspect", [function () {
// ...
Remove ngTouch
and uuid4
or add scripts, referencing to their definition, and it should work.
from angular-aop.
Okay, it works in plnkr, but not locally, so I played around a bit. If locally, I disable our single file merging, and load AOP separately it works, however, if I load it all in one file, I get the error in my original post when I include:
.config(function($provide, executeProvider) {
executeProvider.annotate($provide, {
DummyService: [ {
jointPoint: "after",
advice: "LogAspect"
} ]
})
Not sure yet why merging into one file leads to this error, but its a start.
from angular-aop.
Are you sure you concatenate all script files in the appropriate order?
from angular-aop.
Yep! The order in the minified file was near identical to the exploded version (only difference was a completely external dependency used to be first, and with angular and angular-aop exploded out, is now 3rd, so should have no effect).
That said, I'm running into a problem with aop not applying to my non-dummy services. It's an angular service (v.s. factory as above, though that should have no effect) named in lowercase, api
, and it seems no method calls attached to this service invoke my aop logger. No errors generated or anything, just nothing happening.
from angular-aop.
We can close this issue.
Please mail me with details (code snippets) of the AngularAOP code you can't make work.
from angular-aop.
I would say this particular issue is still open given minification leads to this error, but that's your call. As for some services not working, it seems aop doesn't play nicely with angular services (js classes).
For reference, a service:
.service("DummyService", ["$log", function ($log) {
var DummyService = function () {
};
DummyService.prototype.foo = function () {
$log.info("---- DummyService::foo ----");
};
DummyService.prototype.bar = function (a, b) {
$log.info("---- DummyService::bar ----");
return a * b;
};
DummyService.prototype.baz = function (a, b, c) {
$log.info("---- DummyService::baz ----");
return c(a * b);
};
return new DummyService();
}])
Does not invoke logging at all when configured:
.config(function ($provide, executeProvider) {
executeProvider.annotate($provide, {
DummyFactory: [{
jointPoint: "after",
advice: "AspectLogger"
}],
DummyService: [{
jointPoint: "after",
advice: "AspectLogger"
}]
})
Whereas the factory version does incoke the logger.
from angular-aop.
It is developers' responsibility to manage the order the dependencies of his project are concatenated. The purpose of AngularAOP is only to provide a way to deal with cross-cutting concerns inside your AngularJS project. Even minification tools like uglifyjs delegate the concatenation order to the developer since the dependency resolution is a hard problem, especially in weakly typed languages like JavaScript. This is the reason I closed the issue, since it is not relevant to the framework.
In your code snippet you don't define DummyService
properly. Take a look at AngularJS' documentation.
Here is how it should be:
var DemoApp = angular.module('DemoApp', ['AngularAOP']);
DemoApp.controller('DummyController', function (DummyService) {
DummyService.foo();
});
DemoApp.service("DummyService", ["$log", function DummyService($log) {
this.foo = function () {
$log.info("---- DummyService::foo ----");
};
this.bar = function (a, b) {
$log.info("---- DummyService::bar ----");
return a * b;
};
this.baz = function (a, b, c) {
$log.info("---- DummyService::baz ----");
return c(a * b);
};
}]);
DemoApp.factory('Logger', function () {
return function (args) {
console.log('Dummy logger');
};
});
DemoApp.config(function ($provide, executeProvider) {
executeProvider.annotate($provide, {
DummyService: [{
jointPoint: 'after',
advice: 'Logger'
}]
});
});
<!DOCTYPE HTML>
<html lang="en" data-ng-app="DemoApp">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body data-ng-controller="DummyController">
Open console to see the action!
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<script src="https://rawgithub.com/mgechev/angular-aop/master/build/angular-aop.min.js"></script>
<script src="demo.js"></script>
</body>
</html>
from angular-aop.
Okay, so my service does work when defined as I have done, but yes, it is a mild divergence from Angular docs.
Maybe make a note on the README that typescript classes will not play with AOP? (or something more generic about the service requiring strict conformance to the angular docs?)
I'll see how much effort would be involved in porting my necessary code away from classes and services into simple factories. Thanks.
from angular-aop.
It is not necessary to use factory
instead of service
, but you should use service
the right way. service
accepts a function, which is later invoked with new
. The result is being cached internally in the provider
.
from angular-aop.
Unfortunately because of how typescript generates classes, we don't have the ability to create services the right way. We were using them canonically:
.service("api", ["$log", APICaller]);
but when APICaller
is a typescript class, it seems to be ignored by AOP. I attempted a few different dummy samples that were structured similarly to the output of typescript, which is what led to the code above.
Fortunately in our case, it's not too difficult to swap out the typescrip class
construct for a module with an initialize function, which plays nicely with AOP.
from angular-aop.
Ok, thanks for the quick feedback! Tomorrow, I will try to reproduce this issue with typescript and resolve it.
from angular-aop.
AngularAOP didn't add wrappers to methods defined in the prototype.
The newest content in the master branch has a deep
property, which indicates whether such wrappers should be added. Here is demo:
var DemoApp = angular.module('DemoApp', ['AngularAOP']);
DemoApp.controller('DummyController', function (DummyService) {
DummyService.foo();
});
interface ILogger {
info: Function;
}
class DummyService {
log: ILogger;
constructor($log) {
this.log = $log;
}
foo() {
this.log.info("---- DummyService::foo ----");
}
bar(a: number, b: number) {
this.log.info("---- DummyService::bar ----");
return a * b;
}
baz(a: number, b: number, c: Function) {
this.log.info("---- DummyService::baz ----");
return c(a * b);
}
}
DemoApp.service("DummyService", ["$log", DummyService]);
DemoApp.factory('Logger', function () {
return function (args) {
console.log('Dummy logger');
};
});
DemoApp.config(function ($provide, executeProvider) {
executeProvider.annotate($provide, {
DummyService: [{
jointPoint: 'after',
advice: 'Logger',
deep: true
}]
});
});
from angular-aop.
beautiful! Thanks so much for extending~ works beautifully.
from angular-aop.
If you are using AngularAOP via bower it will not work yet. Tonight I will create a new tag.
from angular-aop.
If you want to use it via bower you can:
bower install angular-aop#0.3.1
from angular-aop.
@mgechev thanks! Was running with #master but will be nice to swap back to versioned land. Thanks so much for the help, and for the quick fix!
from angular-aop.
Related Issues (12)
- Enhancement: add pointcut onNotify HOT 4
- ngResource gets incorrectly wrapped into a function aspect HOT 2
- AngularAOP for advising controller HOT 2
- IE9 HOT 10
- joinpoint.proceed() HOT 2
- resolveArgs is empty in onResolve and AfterResolve HOT 2
- How can I use the library for AOP on every controller and directive function call? HOT 5
- Name of the original function cannot be determined when function called without a context HOT 6
- Reduce the number of recursively wrapped aspects HOT 3
- Enhancement: aspect be able to alter the arguments and return values HOT 9
- Circular dependency when using woven service (or dependent one) in the aspect HOT 2
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-aop.