5
votes

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 :)

2
What do you mean by component?sebenalern
I've updated the question. I'm using an Angular 1.5 component, and I have no idea how to inject an Angular service in it. Since Angular 1.5 is new, I could not find any documentation either.lostsoul29
Are you getting an error message?sebenalern
I updated my answer. I think it should help.sebenalern

2 Answers

5
votes

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!!

0
votes

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