Skip to content Skip to sidebar Skip to footer

Extending $resource Of Angularjs Using Iresourceclass Of Typescript

I am developing SPA using Asp.Net Web API and AngularJS. I also use TypeScript to get static typing. So, I added DefinitelyTyped angularjs. As I am using RESTfull services. I thoug

Solution 1:

First define your model, the interface that will describes your employee.

// Define an interface of the object you want to use, providing it's propertiesinterface IEmployee extends ng.resource.IResource<IEmployee>
{
    id: number;
    firstName : string;
    lastName : string;
}

Then create an interface that describes the resource you will create.

// Define your resource, adding the signature of the custom actions
interface IEmployeeResource extends ng.resource.IResourceClass<IEmployee>
{
    update(IEmployee) : IEmployee;
}

Create the EmployeeResource factory:

var myApp = angular.module('myApp', ['ngResource']).factory('EmployeeResource', 
    ['$resource', ($resource : ng.resource.IResourceService) : IEmployeeResource => {

        // Define your custom actions here as IActionDescriptorvar updateAction : ng.resource.IActionDescriptor = {
            method: 'PUT',
            isArray: false
        };

        // Return the resource, include your custom actionsreturn <IEmployeeResource> $resource('/api/employee/:id', { id: '@id' }, {
            update: updateAction
        });

    }]);

Inject your EmployeeResource into a controller:

myApp.controller('TestCtrl', ['$scope', 'EmployeeResource', ($scope, Employee : IEmployeeResource) => 
{
    // Get all employeesvar employees : Array<IEmployee> = Employee.query();

    // Get specific employee, and change their last namevar employee : IEmployee = Employee.get({ id: 123 });
    employee.lastName = 'Smith';
    employee.$save();

    // Custom actionvar updatedEmployee : IEmployee = Employee.update({ id: 100, firstName: "John" });
}]);

Creating a new employee instance:

You can create an instance of type IEmployee by newing the EmployeeResource factory.

myApp.controller('TestCtrl', ['$scope', 'EmployeeResource', ($scope, Employee : IEmployeeResource) => 
{
    var myEmployee : IEmployee = newEmployee({ firstName: "John", lastName: "Smith"});
    myEmployee.$save();
}

So in the case above we inject our IEmployeeResource as Employee. We can then new this object to create an IEmployee.

Solution 2:

I totally agree with Scott's answer: https://stackoverflow.com/a/21786326/2677975

I do have one addition: In my project, I've create the class ServiceModel<T>, which implements the interface IActionDescriptor.

moduleCommon.ApiService {
    exportclassHttpHeaders {
        'Content-Type': string;
        Accept: string;
    }

    exportclassServiceModel<T> implements ng.resource.IActionDescriptor {
        publicmethod: string = 'GET';
        publicparams: T;
        publicisArray: boolean = false;
        publicurl: string;
        publicheaders: HttpHeaders = newHttpHeaders()
    } 
}

Then, I can setup the method in my controller, just as Scott did, but now, the IDE will have type completion on the headers (and the params later on)

exportinterface IProfileServiceResource extends ng.resource.IResourceClass<IProfileDataModelDef> {
    SaveProfileImage(profileImageUri: Profile.Model.UserProfileModel): ng.resource.IResource<Array<any>>;
}

exportclassProfileApiServiceimplementsCommon.ApiService.IApiServiceBase<IProfileServiceResource> {

    publicSaveProfileImage: Common.ApiService.ServiceModel<Profile.Model.UserProfileModel>;

    constructor() {    
        this.SaveProfileImage = newCommon.ApiService.ServiceModel<Profile.Model.UserProfileModel>();
        this.SaveProfileImage.method = "POST";
        this.SaveProfileImage.url = "/api/Profile/SaveProfileImage";
        this.SaveProfileImage.headers["Content-Type"] = 'application/json';
}

I made this as an additional answer, since it only serves to provide types for the headers and the params.

Post a Comment for "Extending $resource Of Angularjs Using Iresourceclass Of Typescript"