Reputation: 756
Can anyone give an example on using services with Angular 1.5 components?
I'm trying to inject a service in an Angular 1.5 component, but it doesn't work.
I have a login component like so:
class Login {
constructor($scope, $reactive, $state, myService) {
console.log(myService.somevariable); //doesn't work
}
}
// create a module
export default angular.module(name, [
angularMeteor
]).component(name, {
templateUrl: 'imports/ui/components/${name}/${name}.html',
controllerAs: name,
controller: Login
});
My service looks like this:
angular.module(name).service("myService", function () {
this.somevariable = 'somevalue';
});
I just cant seem to be able to get the service injected in the component.What am I doing wrong?
SOLUTION:
With sebenalern's help, I got it working.
I needed a service to validate an email address using a regular expression. I did it like this:
import angular from 'angular';
import angularMeteor from 'angular-meteor';
class Validator {
validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
}
const name = 'validator';
// create a module
export default angular.module(name, [
angularMeteor
])
.service("Validator", Validator);
I then injected the service like so:
import {name as Validator} from '../../../api/services/validator'
class Login {
constructor($scope, $reactive, $state, Validator) {
'ngInject';
this.$state = $state;
$reactive(this).attach($scope);
this.Validator = Validator;
}
login() {
if(this.Validator.validateEmail(this.credentials.email)) {
// email is valid.
}
}
}
const name = 'login';
export default angular.module(name, [
angularMeteor,
Validator
]).component(name, {
templateUrl: `imports/ui/components/${name}/${name}.html`,
controllerAs: name,
controller:Login
})
Hope this helps :)
Upvotes: 5
Views: 11786
Reputation: 545
Here is how I am doing it and it works well. It works fine with classes. I assume you are using TypeScript.
class AdminHomeService {
consignment: IConsignment;
get: () => IConsignment;
constructor() {
this.consignment = new Consignment();
this.consignment.id = 10;
this.consignment.customer = "Customer3";
this.consignment.customerList = [{ id: 1, name: "Customer1" }, { id: 2, name: "Customer2" }, { id: 3, name: "Customer3" }];
this.consignment.shipperList = [{ key: "1", value: "Shipper1" }, { key: "2", value: "Shipper2" }, { key: "3", value: "Shipper3" }];
this.consignment.consigneeList = [{ key: "1", value: "Consignee1" }, { key: "2", value: "Consignee2" }, { key: "3", value: "Consignee3" }];
this.consignment.billingList = [{ key: "1", value: "Billing1" }, { key: "2", value: "Billing2" }, { key: "3", value: "Billing3" }];
this.consignment.carrierList = [{ key: "1", value: "Carrier1" }, { key: "2", value: "Carrier2" }, { key: "3", value: "Carrier3" }];
this.get = () => {
return this.consignment;
}
}
}
class AdminHomeComponentController {
consignment: IConsignment;
selectedCustomer: any;
static $inject = ["adminHomeService"];
constructor(private adminHomeService: AdminHomeService) {
this.consignment = new Consignment();
this.consignment = this.adminHomeService.get();
this.selectedCustomer = {};
this.selectedCustomer.selected = { "name": this.consignment.customer };
}
customerAddClick(): void {
}
}
class AdminHomeComponent implements ng.IComponentOptions {
bindings: any;
controller: any;
templateUrl: string;
$routeConfig: angular.RouteDefinition[];
constructor() {
this.bindings = {
textBinding: "@",
dataBinding: "<",
functionBinding: "&"
};
this.controller = AdminHomeComponentController;
this.templateUrl = "templates/admin.home.html";
//this.$routeConfig = [
// { path: "/admin", name: "AdminHome", component: "adminHome", useAsDefault: true }
//];
}
}
angular.module("adminHome", [])
.component("adminHome", new AdminHomeComponent())
.service("adminHomeService", AdminHomeService);
This post helped me a lot: http://almerosteyn.com/2016/02/angular15-component-typescript
Upvotes: 0
Reputation: 2561
So one problem I see is you should be using the keyword this inside the constructor
this.$scope = $scope;
Another thing it is probably easier to stay away from classes and use functions:
class Login {
constructor($scope, $reactive, $state, myService) {
console.log(myService.somevariable); //doesn't work
}
}
Becomes:
angular
.module('name')
.service('myService', myService);
function myService () {
this.somevariable = 'somevalue';
}
To me it seems a lot cleaner. Also another thing about ES6 classes is
ES6 Classes are not hoisted, which will break your code if you rely on hoisting
For more info see link.
Now here is the working code I came up with:
First we declare the module:
angular.module('name', []);
Next we register our service and then create the service definition:
angular
.module('name')
.service('myService', myService);
function myService () {
this.somevariable = 'somevalue';
}
Next we do the same procedure for our controller and also we inject $scope and our service into it.
angular
.module('name')
.controller('Login', Login);
function Login($scope, myService) {
$scope.someVar = myService.somevariable;
}
Last I registered our component:
angular
.module('name')
.component('my-html', {
templateUrl: 'my-html.html',
controller: Login
});
And that is it on the javascript side.
Here is my html code:
<!DOCTYPE html>
<html lang="en-us" ng-app='name'>
<head>
<script src="//code.angularjs.org/1.5.0-rc.1/angular.js"></script>
<script src="controller.js"></script>
</head>
<body >
<h ng-controller="Login">{{ someVar }}</h>
</body>
</html>
I hope this helps!!
Upvotes: 5