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 servic
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
.
module Common.ApiService {
export class HttpHeaders {
'Content-Type': string;
Accept: string;
}
export class ServiceModel<T> implements ng.resource.IActionDescriptor {
public method: string = 'GET';
public params: T;
public isArray: boolean = false;
public url: string;
public headers: HttpHeaders = new HttpHeaders()
}
}
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)
export interface IProfileServiceResource extends ng.resource.IResourceClass<IProfileDataModelDef> {
SaveProfileImage(profileImageUri: Profile.Model.UserProfileModel): ng.resource.IResource<Array<any>>;
}
export class ProfileApiService
implements Common.ApiService.IApiServiceBase<IProfileServiceResource> {
public SaveProfileImage: Common.ApiService.ServiceModel<Profile.Model.UserProfileModel>;
constructor() {
this.SaveProfileImage = new Common.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
.
First define your model, the interface that will describes your employee.
// Define an interface of the object you want to use, providing it's properties
interface 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 IActionDescriptor
var updateAction : ng.resource.IActionDescriptor = {
method: 'PUT',
isArray: false
};
// Return the resource, include your custom actions
return <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 employees
var employees : Array<IEmployee> = Employee.query();
// Get specific employee, and change their last name
var employee : IEmployee = Employee.get({ id: 123 });
employee.lastName = 'Smith';
employee.$save();
// Custom action
var updatedEmployee : IEmployee = Employee.update({ id: 100, firstName: "John" });
}]);
Creating a new employee instance:
You can create an instance of type IEmployee
by new
ing the EmployeeResource
factory.
myApp.controller('TestCtrl', ['$scope', 'EmployeeResource', ($scope, Employee : IEmployeeResource) =>
{
var myEmployee : IEmployee = new Employee({ 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
.