Search code examples
javascriptangularjsweb-component

Use one component in multiple states with different service methods


I want to build a component that I would be able to re-use in different states, because the functions it performs are quite similar. The problem is that it is supposed to use different methods from my service according to the state where it is rendered. Considering I've got these states:

$stateProvider
    .state('create', {
        url: 'create',
        component: 'myComponent',
        resolve: {
           data: function (myService) {
               return myService.getData();
           }
        }
    })
    .state('edit', {
         url: 'edit',
         component: 'myComponent',
         // another resolve
    })
    // and so on

And I have a service with the following methods:

class myService {
    // constructor($http) { this._$http = $http; }
    create(smth) {
        return this._$http.post(`${apiUrl}/smth`, smth).then(res => res.data);
    }

    edit(smth) {
        return this._$http
            .put(`${apiUrl}/smth/${smth.id}`, smth)
            .then(res => res.data);
    }
}

And my component:

let myComponent = {
    //bindings: {},
    controller: function () {};
    template: myTemplate
}

So that if my component is rendered in create state, it would use create() method from myService correspondingly, and the same for edit and other states I would have. How could I design my component to work in a such way?


Solution

  • For example, you can pass binding in one of the cases (like edit):

    bindings: { isEditState: "<?"}
    

    Service:

    class myService {
    // constructor($http) { this._$http = $http; }
      makeRequest(smth, method) {
        return this._$http[method](smth).then(res => res.data); // because they are pretty similar in your example
      }
    }
    

    Then in component:

    makeReuest(smth) {
      const reqMethod = isEditState ? "put" : "post";
      this.myService.makeRequest(smth, method);
      // ...
    }
    

    Finally, in routes, you can pass template instead of component :

    $stateProvider
    .state('create', {
        url: 'create',
        template: '<my-component></my-component>',
        resolve: {
           data: function (myService) {
               return myService.getData();
           }
        }
    })
    .state('edit', {
         url: 'edit',
         template: '<my-component is-edit-state="true"></my-component>',
         // another resolve
    });