0

Consider this simple snippet of an AngularJS 2 application:

TestObject

export class TestObject {
     id: number;
     name: string;
}

TestService

[...]

export class TestService {
    constructor(private http: Http) {}

    test(): Observable<TestObject> {
        return this.http
           .get("http://www.example.com")
           .map(this.save)
           .catch(this.fail);
    }

    private save(response: Response) {
        let testObject: TestObject = <TestObject> response.json();
        return testObject || {};
    }

    private fail(error: any) {
        return Observable.throw("error!");
    }
}

AppComponent

[...]

export class AppComponent implements OnInit {

    testObject: TestObject;

    constructor(private testService: testService) {}

    ngOnInit() {
        this.testService.test().subscribe(
            data => { 
                this.testObject = new TestObject();
                console.log(this.testObject); // prints (empty) TestObject
                this.testObject = data; 
                console.log(this.testObject); // prints object, not TestObject?
            },
            error => { }
        );
    }
}

Here my questions:

1) Why does my application print out (using Chrome Inspector) object and not TestObject as type?

2) The property testObject of class AppComponent should be of type TestObject. Why does my application not fail?

3) How can I achieve that I really get TestObject? What would be the best way to do it? Of course I could just manually fill up my TestObject, but I hoped there is some way of automatically mapping the json to my object.

andreas
  • 7,844
  • 9
  • 51
  • 72
  • I think my problem is partially answered here: http://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class – andreas Sep 27 '16 at 16:28

1 Answers1

0

Here is an answer that I wrote to a question which explained the handling of observables in angular2.

Angular 2 http post is returning 200 but no response is returned

Here you can see how I am handling the Response object as returned by the service. It is very important that you return your response object from the map function in service. Similarly you can convert your response object to typescript type by casting your response object. The example can be:

this._loginService.login(this.username, this.password)  
    .subscribe(
        (response) => {
            //Here you can map the response to a type.
            this.apiResult = <IUser>response.json();
            //You cannot log your object here. Here you can only map.
        },
        (err) => {
            //Here you can catch the error
        },
        () => {
          //this is fired after the api requeest is completed.
          //here you can log your object.
          console.log(this.apiResult);
          //result will only be shown here.
        }
    );

Here, it can be clearly seen that I am casting the response object to IUser type.

Another thing is while handling apiresponse in your component it is to be noted that the subscribe function has three arguments and if you will like to log your object, you must do it in the last function of subscribe.

Hope this helps!

your call must be like

ngOnInit() {
    this.testService.test().subscribe(
        (data) => { 
            this.testObject = new TestObject();
            console.log(this.testObject); // prints (empty) TestObject
            //only mapping
            this.testObject = data; 
        },
        error => { },
        () => {
            console.log(this.testObject);
        }
    );
}
Community
  • 1
  • 1
Abhinandan
  • 429
  • 8
  • 13
  • Have you tried `console.log(this.apiResult)`? I am also doing the casting in the subscribe part, but it still shows `object` in Chrome Inspector. – andreas Sep 27 '16 at 16:06
  • you should log the object in third parameter which is like onComplete function, which i have showed in the above example. The first parameter is for mapping, the second is for error and the third one is where the request is completed. – Abhinandan Sep 27 '16 at 16:09
  • I have done that as well, I could not see any difference. – andreas Sep 27 '16 at 16:11
  • Have you changed your map function in your service to return the response as shown by me. It is very important to return your response from here. – Abhinandan Sep 27 '16 at 16:12
  • Thank you. Yes I am returning it in the mapping function (see above) and tried what you posted, but it still returns `object`... Have you tried it successfully? – andreas Sep 27 '16 at 16:25
  • All of your implementation is same as mine except that I am logging the object after error method in subscribe as I have shown in my edited answer and it is working. – Abhinandan Sep 27 '16 at 16:56