Reputation: 135
Does anyone encounter this error before and could shed some light for me? I was stuck for days :(
I'm trying to call my Web API function using a Promise function in my typescript file. Basically I am trying to pass a list of keys(int or string) to my Web API and i encountered the error there. Does anyone know how to solve this issue with (must be instanceof Promise error) ?
Controller:
import { Injectable } from 'angular2/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
export class WorkOrderService {
private tasks: any;
private taskItems: any;
private woSummary: any;
static get parameters() {
return [[Http]];
}
public constructor(private http: Http) {
}
public DownloadWO(ClientApiUrl, workOrders) {
var headers = new Headers();
headers.append('Content-Type', 'application/json');
var workOrderKeys = new Array();
for (let workOrder of workOrders) {
if (workOrder.checked) {
workOrderKeys.push(workOrder.WorkOrderKey);
}
}
//ERROR CANT SOLVE
return new Promise((resolve, reject) => {
this.http.post(ClientApiUrl + "workorder/UpdateAndLockWorkOrders", workOrders, { headers: headers })
.map(res => res.json())
.subscribe(
data => {
resolve(data);
},
err => {
reject(err);
});
});
}
}
Behind-code .ts
import { Component } from '@angular/core';
import { AlertController, ModalController, NavController, LoadingController } from 'ionic-angular';
import { Global } from '../../app/global';
import { LocationService } from '../../services/locationService';
import { DepartmentService } from '../../services/departmentService';
import { WorkOrderService } from '../../services/workOrderService';
import { HomePage } from '../home/home';
import { ModalPmTaskPage } from './modal-pmTask'
@Component({
selector: 'page-downloadWO',
templateUrl: 'downloadWO.html'
})
export class DownloadWOPage {
private sites: any;
private selectPLocID: string;
private selectedSite: number;
private parentLocations: any;
private selectedPLocation: number;
private locations: any;
private selectedLocation: number;
private departments: any;
private selectedDepartment: number;
private fromDate: Date;
private toDate: Date;
private workOrders: any;
private isLock: number;
private pmTaskItems: any;
public constructor(
private navCtrl: NavController,
private workOrderService: WorkOrderService,
private locationService: LocationService,
private departmentService: DepartmentService,
private global: Global,
private alertCtrl: AlertController,
private modalCtrl: ModalController,
private loadingCtrl: LoadingController) {
}
public download() {
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
//Download & Lock WorkOrders
this.workOrderService.DownloadWO(this.global.getClientApiUrl(), this.workOrders).then(data => {
loader.dismiss();
let alert = this.alertCtrl.create({
title: 'Success',
subTitle: 'Work Orders has downloaded sucessfully',
buttons: [{
text: 'OK',
handler: () => {
this.navCtrl.push(HomePage);
}
}]
});
alert.present();
}).catch(function (err) {
loader.dismiss();
let alert = this.alertCtrl.create({
title: 'Error',
subTitle: err,
buttons: [{
text: 'OK'
}]
});
alert.present();
});
}
}
HTML:
<ion-content>
...
<ion-item-divider color="primary">Select Work Order</ion-item-divider>
<ion-scroll scrollY="true" style="height:50vh;">
<ion-list>
<ion-item text-wrap *ngFor="let workOrder of workOrders;">
<ion-checkbox [(ngModel)]="workOrder.checked" >{{workOrder.checked}}</ion-checkbox>
<ion-label>
<h2>
<b>Work Order ID:</b> {{workOrder.WorkOrderID}}
</h2>
<h2>
<b>PM Task ID:</b> {{workOrder.TaskId}}
</h2>
<h2>
<b>Asset ID:</b> {{workOrder.AssetID}}
</h2>
<button ion-button color="secondary" (click)="viewTaskItemFromServer(workOrder.WorkOrderKey)">View PM Task Items</button>
</ion-label>
</ion-item>
</ion-list>
</ion-scroll>
<button ion-button block (click)="download()">Download</button>
</ion-content>
C# Web API:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using MaxPro_WebService.Interface.Controllers;
using MaxPro_WebService.Interface.Models;
using System.Net.Http.Headers;
using System.Web.Script.Serialization;
using CMMS.AssetsMaintMgmt_BLLAx;
using System.Transactions;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace MaxPro_Client_WebService.Controllers
{
[RoutePrefix("api/WorkOrder")]
public class WorkOrderController : ApiController, IWorkOrderController
{
[Route("UpdateAndLockWorkOrders")]
[HttpPost]
public async Task<HttpResponseMessage> UpdateAndLockWorkOrders([FromBody]List<string> workOrderKeys)
{
string errorMsg, exMsg;
errorMsg = exMsg = string.Empty;
DateTime dtNow = DateTime.Now;
errorMsg = exMsg = string.Empty;
try
{
using (var client = new HttpClient())
{
////IL: TRY TO PASS IN CLASS
//client.BaseAddress = new Uri("http://localhost/MaxPro_WebService/");
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//var response = await client.PostAsJsonAsync("api/WorkOrder/uploadWorkOrders", workOrders);
IEnumerable<WorkOrder> workorders = null;
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ServerBaseURLAddress"]); //Question how to get URL of web service
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsJsonAsync("api/WorkOrder/GetWorkOrders", workOrderKeys);
if (response.IsSuccessStatusCode)
{
string responseString = response.Content.ReadAsStringAsync().Result;
//JSON Object TO Work Order class
workorders = response.Content.ReadAsAsync<IEnumerable<WorkOrder>>().Result;
if (InsertRecords(workorders, out errorMsg))
{
//IL: 3/2/2017 working for LockWorkOrder
//client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ServerBaseURLAddress"]); //Question how to get URL of web service
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
response = await client.PostAsJsonAsync("api/WorkOrder/LockWorkOrders", workOrderKeys);
if (response.IsSuccessStatusCode)
{
//LOCKING SUCCESSFUL
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
//LOCKING UNSUCCESSFUL
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
//Something has gone wrong, handle it here
}
}
else
{
//SAVE WO UNSUCCESSFUL
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
//Something has gone wrong, handle it here
}
}
else
{
//Something has gone wrong, handle it here
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
}
}
}
catch (TransactionAbortedException ex)
{
exMsg = ex.Message;
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
}
catch (ApplicationException ex)
{
exMsg = ex.Message;
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
}
catch (Exception ex)
{
exMsg = ex.Message;
return Request.CreateErrorResponse((HttpStatusCode)422, new HttpError(exMsg));
}
}
}
}
Enviroments:
IDE: VS2015 Cordova CLI: 6.5.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
OS: Windows 7
Node Version: v7.6.0
Xcode version: not installed
Upvotes: 0
Views: 1457
Reputation: 29614
The http
module of Angular 2 returns an Observable and not a promise.
You can convert it to a promise using Observable.toPromise()
to use in your promise chain.
Try:
return new Promise((resolve, reject) => {
this.http.post(ClientApiUrl + "workorder/UpdateAndLockWorkOrders", workOrders, { headers: headers })
.map(res => res.json()).toPromise()//convert to promise
.then(//call then instead of subscribe to form the promise chain.
data => {
resolve(data);
},
err => {
reject(err);
});
});
Another way is simplifying without encapsulating with a new promise:
return this.http.post(ClientApiUrl + "workorder/UpdateAndLockWorkOrders", workOrders, { headers: headers })
.map(res => res.json()).toPromise()//convert to promise
Your catch in the end will get the error from the chain.
Upvotes: 2
Reputation: 101
Try specifying type after promise, something like this :
return new Promise < any> ((resolve, reject).....
Upvotes: 0