title: Return Promise in Angular with typescript as custom Data Type
body: <p>I am new in Typescript, and I am trying to return a promise with and object of type <code>Device</code>, but I cannot reach it.</p>
  
  <p>The problem is when I return a Mock everything works good, but when I connect to a real API I have problems here <code>response.json().data as Device</code>.</p>
  
  <p>When I ask for the data in the server and then I try to print this in the template, everything its gone and in the console I have <code>Undefined</code>. 
  Also the <code>console.log</code> that is in <code>device.component.ts</code> in the function <code>getDevices()</code> print like the old status of the object, because when I change the data appear the data that was supposed to show before.</p>
  
  <p>I have a few questions like:</p>
  
  <ol>
  <li><p>How can I access to the <code>response.json().data</code> in the <code>.then</code> of the promise to see what's the structure or what's the data that it has ?</p></li>
  <li><p>How can I map (I think this terminology is correct for <code>Observable</code>, but I don't know how to say it for <code>Promise</code>s) my <code>device</code> object with the data of the API ?</p></li>
  </ol>
  
  <p><strong>device.component.ts</strong></p>
  
  <pre><code>import { Component, OnInit, Input } from '@angular/core';
  import { Device } from './device';
  import { DeviceService } from './device.service';
  
  @Component({
  selector: 'app-device',
  templateUrl: './device.component.html'
  })
  
  export class DeviceComponent implements OnInit {
      @Input() private device: Device;
      constructor(private deviceService: DeviceService) {};
  
      ngOnInit(): void {
          // this.getDevice(40072);
          this.deviceService.getDeviceMock().then(device =&gt; this.device = device);
      }
  
      getDevice(id: number): void {
          this.deviceService.getDevice(id).then(device =&gt; this.device = device);
          console.log(this.device);
          // this.deviceService.getDeviceMock().then(device =&gt; this.device = device);
      }
  
      search(id: number): void {
          this.getDevice(id);
  }
  
      save(): void {
          this.deviceService.setDevice(this.device);
      }
  }
  </code></pre>
  
  <p><strong>device.component.html</strong></p>
  
  <pre><code>&lt;input [(ngModel)]="idSearch" type="text" placeholder="Insert ID"  &gt;
  &lt;button (click)="search(idSearch)"&gt;Search&lt;/button&gt;
  
  &lt;div *ngIf="device"&gt;
  &lt;div&gt;
    &lt;label&gt;Uid: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Uid" placeholder="Uid"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;VigilId: &lt;/label&gt;
  &lt;input [(ngModel)]="device.VigilId" placeholder="VigilId"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;CmfPhoneNumber: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.CmfPhoneNumber" placeholder="CmfPhoneNumber"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;ReportInterval: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.ReportInterval" placeholder="ReportInterval"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;GeoLocationHighAccuracy: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.GeoLocationHighAccuracy" placeholder="GeoLocationHighAccuracy"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;AlarmCancelTimeout: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.AlarmCancelTimeout" placeholder="AlarmCancelTimeout"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;AdherenceCheckInterval: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.AdherenceCheckInterval" placeholder="AdherenceCheckInterval"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;PreAlarmPeriod: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.PreAlarmPeriod" placeholder="PreAlarmPeriod"&gt;
  &lt;/div&gt;
  
  &lt;div&gt;
    &lt;label&gt;PingInterval: &lt;/label&gt;
    &lt;input [(ngModel)]="device.Model.RuntimeSettings.PingInterval" placeholder="PingInterval"&gt;
  &lt;/div&gt;
  
  &lt;button (click)="save()"&gt;Send&lt;/button&gt;
  </code></pre>
  
  <p></p>
  
  <p><strong>device.service.ts</strong></p>
  
  <pre><code>import { Component } from '@angular/core';
  import { Device } from './device';
  import { Injectable } from '@angular/core';
  import { Headers, Http } from '@angular/http';
  import 'rxjs/add/operator/toPromise';
  
  import { DeviceMock } from './device-mock'
  
  
  @Injectable()
  export class DeviceService {
      // TODO: Create configuration file.
      private apiUrl = 'https://api.com/api2/v2';
      private headers = new Headers({'Authorization': 'xxxx'});
  
      constructor(private http: Http) {};
      getDeviceMock(): Promise&lt;Device&gt; {
          return Promise.resolve(DeviceMock)
      }
  
      getDevice(id: number): Promise&lt;Device&gt; {
          const url = `${this.apiUrl}/device/${id}?names=RuntimeSettings`;
          return this.http.get(url, {headers: this.headers})
              .toPromise()
              .then(response =&gt; response.json().data as Device)
              .catch(this.handleError);
      }
  
      setDevice(device: Device): Promise&lt;Device&gt; {
          this.headers.set('Content-Type', 'application/json');
          const url = `${this.apiUrl}/device/${device.VigilId}?names=RuntimeSettings`;
          return this.http.put(url, JSON.stringify(device), {headers: this.headers})
              .toPromise()
              .then(response =&gt; response.json().data as Device)
              .catch(this.handleError);
      }
  
      private handleError(error: any): Promise&lt;any&gt; {
          console.error('An error occurred', error);
          return Promise.reject(error.message || error);
      }
  };
  </code></pre>
  
  <p><strong>device.ts</strong></p>
  
  <pre><code>export interface Device {
      VigilId: number;
      Uid: string;
      Model: Model;
  };
  
  interface Model {
      RuntimeSettings: RuntimeSettings;
  };
  
  interface RuntimeSettings {
      ReportInterval: number;
      PingInterval: number;
      PreAlarmPeriod: number;
      AdherenceCheckInterval: number;
      AlarmClearTimeout: number;
      AlarmCancelTimeout: number;
      DailyReportInterval: number;
      GeoLocationRetryCount: number;
      GeoLocationHighAccuracy: true;
      GeoLocationTimeOut: number;
      GeoMaxAgeTimeOut: number;
      CmfPhoneNumber: number;
      PalmTouchTrigger: boolean;
      TouchTriggerCooldownPeriod: number;
      DemoMode: boolean;
      DeviceName: string;
      VerboseLogging: boolean;
  };
  </code></pre>
  
  <p>And this is a response of the API</p>
  
  <pre><code>{
      "VigilId": 41,
      "Uid": "Identi",
      "Model": {
          "RuntimeSettings": {
              "ReportInterval": 900,
              "PingInterval": 300,
              "PreAlarmPeriod": 10,
              "AdherenceCheckInterval": 3600,
              "AlarmClearTimeout": 600,
              "AlarmCancelTimeout": 15,
              "DailyReportInterval": 43200,
              "GeoLocationRetryCount": 3,
              "GeoLocationHighAccuracy": true,
              "GeoLocationTimeOut": 5000,
              "GeoMaxAgeTimeOut": 60,
              "CmfPhoneNumber": "",
              "PalmTouchTrigger": true,
              "TouchTriggerCooldownPeriod": 30,
              "DemoMode": false,
              "DeviceName": "",
              "VerboseLogging": false
          }
      }
  }
  </code></pre>