When using Angular 1.x in combination with Typescript, I'm facing some problems.
Considering this code:
get(id): ng.IPromise<Server.MyItem> {
return this.$http.get(`${this.baseAddress}/${id}`).then(d => d.data);
}
It's compiled by tsc, but I 'm getting the following error:
Type 'IPromise<{}>' is not assignable to type 'IPromise'
I tried to use the more specific IHttpPromise
, but it does not do the tricks..
Any idea?
Try casting your data to Server.MyItem
:
get(id): ng.IPromise<Server.MyItem> {
return this.$http.get(`${this.baseAddress}/${id}`).then(d => <Server.MyItem>d.data);
}
You could also use the generic version of the method:
get(id): ng.IPromise<Server.MyItem> {
return this.$http.get<Server.MyItem>(`${this.baseAddress}/${id}`).then(d => d.data);
}
When I was using typescript this is how me and my Sr would implement requests.
First I need two interfaces for my result set from any request. One that extends IHttpPromiseCallbackArg and another for my custom Output. And I always liked to create a third for the actual type that was coming back. In this example I have used Contacts as my factory so I need a IContact interface.
interface ICallback<T> extends ng.IHttpPromiseCallbackArg<T> {
data?: T;
}
interface IOutput<T> {
Output: T,
ErrorMsg: string
}
interface IContact {
ContactID: string;
ContactLastName: string;
ContactFirstName: string;
ContactEmail: string;
ContactPhone: string;
ContactFullName: string;
ModifiedBy?: string;
ModifiedOn?: Date;
CreatedBy: string;
CreatedOn: Date;
}
Then following I need a Notification Factory and RequestHelper Factory
export class NotificationFactory {
success = function (msg: string, title?: string): void {
this.toastr.success(msg, title);
}
error = function (msg: string, title?: string): void {
this.toastr.error(msg, title);
}
static $inject: Array<string> = ['toastr'];
constructor(private toastr: ng.toastr.IToastrService) {
return this;
}
}
export class RequestHelper {
toastSuccess = function (msg: string, title?: string): void {
this.NotificationFactory.success(msg, title);
}
toastError = function (msg: string, title?: string): void {
this.NotificationFactory.error(msg, title);
}
private success = (results: ICallback<IOutput<any>>, options: IOptions): any => {
if (results.data.ErrorMsg) {
this.NotificationFactory.error(results.data.ErrorMsg);
}
if (typeof options.callback === 'function') {
if (options.showSave && !results.data.ErrorMsg) {
this.NotificationFactory.success('Your changes have been saved.');
}
return options.callback(results.data);
}
if (options.showSave && !results.data.ErrorMsg) {
this.NotificationFactory.success('Your changes have been saved.');
}
return results.data;
}
private fail = (err: any, options: IOptions): ng.IPromise<any> => {
if (options.callingFn !== undefined) {
this.NotificationFactory.error('There was an error calling ' + options.callingFn + '. details:' + err.statusText);
}
return err;
}
makeRequest = (request: IRequest, o?: IOptions): ng.IPromise<any> => {
o = o || {};
var vm = this;
return this.$http(request).then((results: ICallback<IOutput<any>>) => {
return vm.success(results, o);
}).catch((err) => {
return vm.fail(err, o);
});
}
static $inject: Array<string> = ['$http', '$state', '$stateParams', 'NotificationFactory'];
constructor(private $http: ng.IHttpService, private $state: any, private $stateParams: IMyStateParams, private NotificationFactory: NotificationFactory) {
return this;
}
}
Then in any factory I can inject my Request Helper and call 'makeRequest'
export class ContactsFactory {
getData = (): ng.IPromise<IOutput<Array<IContact>>> => {
let req = { method: 'GET', url: '/Contacts/GetContacts?d=' + Date.parse(new Date().toString()).toString() };
return this.RequestHelper.makeRequest(req, { callingFn: 'ContactsFactory.getData', callback: null, showSave: false });
}
getContactByID = (id: string): ng.IPromise<IOutput<Array<IContact>>> => {
let req = { method: 'POST', url: '/Contacts/GetContactByID', data: { id: id } };
return this.RequestHelper.makeRequest(req, { callingFn: 'ContactsFactory.getContactByID', callback: null, showSave: false });
}
static $inject: Array<string> = ['RequestHelper', 'UsersFactory'];
constructor(private RequestHelper: RequestHelper, private UsersFactory: UsersFactory) {
return this;
}
}
And lastly my controller that would call my factory
export class ContactsController {
loading: boolean;
contacts: Array<IContact>;
initialize = (): void => {
this.loading = true;
this.ContactsFactory.getData().then((results) => {
this.contacts = results.Output;
this.loading = false;
});
});
}
static $inject: Array<string> = ['ContactsFactory'];
constructor(private ContactsFactory: ContactsFactory) {
this.initialize();
}
}
Hopefully this helps. Also I am upvoting @Franks answer since I am type casting my request as he has stated. Credit to Phxjoe for help, My Sr Developer at the time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.