1

I just started angular few days ago and did the tour-of-heroes app. I'm trying to add a set of steps to display in a textarea based on which hero is selected. If hero1 is selected it should display step 1, and when "next" is clicked, it should display step 2. I am having trouble figuring out how to get it to display correctly. Currently when I hit next it displays "[object Promise]". Any help would be appreciated.

calibration-detail.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Headers, Http } from '@angular/http';
import { Hero } from '../hero.class';
import { Step } from '../step.class';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import { InMemoryDataService } from '../in-memory-data.service';
import { HeroService } from '../hero.service';
import { StepService } from '../step.service';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';

@Component({
moduleId: module.id,
selector: 'app-calibration-detail',
templateUrl: './calibration-detail.component.html',
styleUrls: ['./calibration-detail.component.css']
})

export class CalibrationDetailComponent implements OnInit {

@Input()
hero: Hero;
step: Step;

private mainStepText: String = "Main window text"; //It doesnt want to accept this.hero.id
private statusStepText: String = "Status window text";

constructor(
 private heroService: HeroService,
 private stepService: StepService,
 private route: ActivatedRoute,
 private location: Location,
 private http: Http,
 //private memoryService: InMemoryDataService
) { }


ngOnInit(): void {
 this.route.params
   .switchMap((params: Params) => this.heroService.getHero(+params['id']))
   .subscribe(hero => this.hero = hero);

 this.route.params
   .switchMap((params: Params) => this.stepService.getStep(+params['id']))
   .subscribe(step => this.step = step);
}

goBack(): void {
this.location.back();
}

save(): void {
this.heroService.update(this.hero)
  .then(() => this.goBack());
}
next(): void {
this.mainStepText = this.stepService.getStep(this.step.id).toString();
}
}

steps.components.ts

import { Component, OnInit } from '@angular/core';
import { Step } from '../step.class';
import { StepService } from '../step.service';
import { Router } from '@angular/router';

@Component({
moduleId: module.id,
selector: 'app-steps',
templateUrl: './steps.component.html',
styleUrls: ['./steps.component.css']
})
export class StepsComponent implements OnInit {
steps: Step[];
selectedStep: Step;

constructor(
private router: Router,
private stepService: StepService) 
{ }

getSteps(): void {
this.stepService.getSteps().then(steps => this.steps = steps);
}

ngOnInit(): void {
this.getSteps();
}

onSelect(step: Step): void {
this.selectedStep = step;
}
gotoDetail(): void {
this.router.navigate(['/detail', this.selectedStep.id]);
}
}

step.service.ts

import { Injectable }    from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Step } from './step.class';

@Injectable()
export class StepService {

private headers = new Headers({'Content-Type': 'application/json'});
private stepsUrl = 'api/steps';  // URL to web api

constructor(private http: Http) { }

getSteps(): Promise<Step[]> {
return this.http.get(this.stepsUrl)
           .toPromise()
           .then(response => response.json().data as Step[])
           .catch(this.handleError);
}

getStep(id: number): Promise<Step> {
const url = `${this.stepsUrl}/${id}`;
return this.http.get(url)
  .toPromise()
  .then(response => response.json().data as Step)
  .catch(this.handleError);
}

private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
} 
}

calibration-detail-component.html

<div class="grid grid-pad">
<div class="col-1-2">
<div *ngIf="hero">
  <h2 class="labelName">{{hero.name}} details!</h2>
</div>
<div *ngIf="step">
  <div class="mainWindow">
    <textarea readonly="textareaEdit" ng-model="textareaValue" [(ngModel)]="mainStepText"></textarea>
 </div>
  <div class="status">
    <textarea readonly="textareaEdit2" style="background-color: #7B797B;" ng-model="textareaValue" [(ngModel)]="statusStepText"></textarea>
  </div>
 </div> 
 </div>
 <div class="col-1-2">
  <div class="container">
    <div class="pull-right">
        <button style ="min-height: 70px" (click)="empty1()">Empty</button>
        <button style ="min-height: 70px" (click)="save()">Ok</button>
        <button style ="min-height: 70px" (click)="next()">Next</button>
        <button style ="min-height: 70px" (click)="goBack()">Back</button>
        <button style ="min-height: 70px" (click)="empty3()">Empty</button>
    </div>
  </div>
  </div>
  </div>

1 Answer 1

1

The problem is in the call to your step service:

this.mainStepText = this.stepService.getStep(this.step.id).toString();

The call to getStep returns a Promise object, which when you run .toString() on it, returns the "[Object Promise]". What you want to do is replace it with the following:

Edit

this.stepService.getStep(this.step.id).then(data => (this.mainStepText = data.name));

This way, you are handling the returned Promise and setting the data it contains to your local variable.

Sign up to request clarification or add additional context in comments.

7 Comments

I tried that, but it says "[ts] Type 'Step' is not assignable to type 'String'. "
That's because you declare the contents of the Promise as type Step inside the service, and then assign it to mainStepText, which is a string. Just change "data" to "data.toString()" in the Promise handler (edited answer above).
Well that fixed the error however instead of [object promise], it now says [object Object].
Can you post the "step.class" file? The .data property of the Step class is probably an object type that does not have its own .toString() function.
export class Step { id: number; name: string; }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.