Typescript / Angular2: Cast JSON to interface with Observable & JSONP

15,405

Solution 1

You could try the following instead:

this.videoData = this.jsonp
    .get('localhost:8080/video/newst/' + count +
                      '?jsonp=JSONP_CALLBACK')
            .map(res => <Video[]>res.json();

Edit

I think that your request doesn't return JSONP content but classical one (JSON). If so, you could try the following:

import { bootstrap }  from 'angular2/platform/browser';
import { Component } from 'angular2/core';
import { HTTP_PROVIDERS, Http } from 'angular2/http';
import "rxjs/add/operator/map";

@Component({
  selector: "app",
  templateUrl: "app.html",
  providers: [HTTP_PROVIDERS]
})
class App {
  private feedData: Observable<Video[]>;

  constructor(private http: Http) { }

  ngOnInit() {
    this.displayNewstVideo(10);
  }

  private displayNewstVideo(count: number) {
    this.videoData = this.http
      .get('localhost:8080/video/newst/' + count)
      .map(res => (res.json() as Video[]))
      .do(videoData => {
        console.log(videoData);
      });
  }
}

bootstrap(App);

Solution 2

I gave a presentation of TypeScript recently, this reminded me of what of the slide's titles "There is no interface!" In TypeScript when you define an interface, it actually compiles down to nothing. Which can be somewhat misleading. I think I understand what you're trying to do though:

The issue is the way that the JSONP object comes back, it's padded. So it sits in the index [1]. Try this instead:

this.videoData = this.jsonp
    .get('localhost:8080/video/newst/' + count +
                      '?jsonp=JSONP_CALLBACK')
            .map(res => <Video[]>res.json()[1]);

Solution 3

Try using a class instead of an interface, so in this case video.model.ts would be:

export class Video {
  constructor(
    public id: number,
    public name: string,
    public description: string,
    public createdAt: string){}
}
Share:
15,405
safari
Author by

safari

Welcome on my Profile I'm 20 years old, probably not a bad Android programmer and now just started with IOS.

Updated on June 27, 2022

Comments

  • safari
    safari almost 2 years

    I'd like to cast my json-array to my interface which I've created and like to display it in the browser. I think there is probably something wrong with my interface but I can't figure it out... What do I need to change to get my code running?

    Interface:

     export interface Video {
      id: number;
      name: string;
      description: string;
      createdAt: string;
    }
    

    app.ts

    import {JSONP_PROVIDERS, Jsonp} from '@angular/http';
    import {Observable} from '../../../node_modules/rxjs';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/share';
    import {Video} from './networking/api';
    
        private videoData: Observable<Video[]>;
        ngOnInit() {
                    this.displayNewstVideo(10);
                }
    
                private displayNewstVideo(count: number) {
                    this.videoData = this.jsonp
                    .get('localhost:8080/video/newst/' + count + '?jsonp=JSONP_CALLBACK')
                    .map(res => (res.json() as Video[]));
                    alert(this.videoData.count);
                }
    

    app.html

    <div class="container">
      <div class="video" style="font-family:sans-serif" *ngFor="#entry of videoData | async;  #i = index">
          <br *ngIf="i > 0" />
          <span class="title" style="font-size:1.2rem">
            <span>{{i + 1}}. </span>
            <a href={{entry.urlDesktop}}>{{entry.name}}</a>
          </span>
          <span> ({{entry.description}})</span>
          <div>Submitted at {{entry.createdAt * 1000 | date:"mediumTime"}}.</div>
        </div>
    

    JSON

    [{
    id: 1,
    name: "Some Name",
    description: "BlaBla",
    createdAt: "2016-05-04 13:30:01.0",
    },
    {
    id: 2,
    name: "Some Name",
    description: "BlaBla",
    createdAt: "2016-05-04 13:30:01.0",
    }]
    

    Edits

    1. I've checked if the request is correct in my network-tab in chrome and it is working as excepted: 200 OK --> Response ist also fine
    2. I edited my code as Thierry stated out and now it is finally showing the first object in my array :-)!! But I get following error now:

    Uncaught EXCEPTION: Error in app/html/app.html:27:11 ORIGINAL EXCEPTION: RangeError: Provided date is not in valid range. ORIGINAL STACKTRACE: RangeError: Provided date is not in valid range. at boundformat (native) at Function.DateFormatter.format (http://localhost:3000/node_modules/@angular/common/src/facade/intl.js:100:26) at DatePipe.transform (http://localhost:3000/node_modules/@angular/common/src/pipes/date_pipe.js:25:37) at eval (http://localhost:3000/node_modules/@angular/core/src/linker/view_utils.js:188:22) at DebugAppView._View_AppComponent1.detectChangesInternal (AppComponent.template.js:377:148) at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:289:44) at DebugAppView.AppView.detectContentChildrenChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:215:37) at DebugAppView._View_AppComponent0.detectChangesInternal (AppComponent.template.js:198:8) at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) ERROR CONTEXT: [object Object]

  • safari
    safari almost 8 years
    Thank you for the tipp - sadly it didn't work ... do you have any other ideas?
  • Thierry Templier
    Thierry Templier almost 8 years
    What do you exactly mean by it doesn't work? ;-) Do you an error? Moreover your alert should be moved into a do operator... In your case are there when it's executed.
  • safari
    safari almost 8 years
    I'd like to parse my json into my interface and for there on I'd like to show the content of my interface in my html. But I do not get any compiler-errors or something. Infact I am a complete new to Typescript and Angular2.
  • Thierry Templier
    Thierry Templier almost 8 years
    In fact res.json() will parse the JSON content. Interfaces are only at design time for type checking. They aren't used at runtime. Do you have your data displayed?
  • safari
    safari almost 8 years
    What do you understand whit displayed? My html keeps empty in my browser - no content is shown. Btw I got the idea doing it like this from here: github.com/Microsoft/typescript-build2016-demos/tree/master/‌​…
  • Thierry Templier
    Thierry Templier almost 8 years
    Your code looks good. Could you have a look at several things: 1. the Network tab of devtools in your browser to see the request 2. add a console.log(res.json()); within the map callback to see the content you have here.
  • Thierry Templier
    Thierry Templier almost 8 years
    I think that I found your problem. Your request isn't a jsonp-compliant one but a classical one. I updated my answer accordingly...
  • safari
    safari almost 8 years
    You were right it was a classical request. Now it is finally showing the first object of my array - thank you! But I got new errors now - I would be glad if you could take a look into it. Kind Regards and thank you for your help!