获取json并将其转换为angular2

时间:2016-09-27 14:52:45

标签: javascript json angular typescript

我已经完成了角度站点的angular2快速入门和英雄之旅教程,以便熟悉它,并且在运行之后,我觉得下一步是使用nodejs添加数据库连接和koa游览英雄应用程序,以增加更多的可扩展性。我在大多数情况下都遵循了https://github.com/mahalo1984/TourOfHeroesWithMongoDb本教程,将数据库从mongo更改为mysql并调整了我需要的内容。

我已经将我的代码上传到https://github.com/nagarz/HeroEditor,以便那些想要查看所有代码的人。

我已经让数据库设置工作了,我得到了json格式化的查询结果,但是当我尝试使用getHeroes服务将其转换为将模板发送到模板时,我得到了这个

EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'slice' of undefined

我是JS的新手,而且我得到了大部分内容,并且我能够根据日志修复错误,但这个是我无法通过的,这一个。我不是JS / angular2向导,但是从我得到的结果来看,服务没有正确选择json,当它尝试将其转换为数组并将其切片以从中获取X个元素时,它给出了错误。我已经尝试了不同的东西让它工作但没有骰子,所以我想我会在这里问我希望有人比我更好(不是那么难,感觉不好)可以看出问题是什么并指出我所以我可以完成整个设置。

这是我用来查询数据库的路线

router.get('/api/heroes', function* (){ var rows = yield db.query("select * from heroes"); this.body = { heroes: rows }; });

当我在浏览器中输入网址http://localhost:3333/api/heroes时,我会像这样在json中获得结果

{"heroes":[{"id":1,"hid":1,"name":"Saitama"},{"id":2,"hid":2,"name":"Genos"},{"id":3,"hid":3,"name":"Watchdog Man"},{"id":4,"hid":4,"name":"Metal BAt"},{"id":5,"hid":5,"name":"Puri Puri Prisoner"},{"id":6,"hid":10,"name":"Speed of sound, Sonic"},{"id":7,"hid":11,"name":"Tatsumaki"}]}

这是我获得响应的地方,并尝试将其转换为数组以处理应用中的信息。

@Injectable()
export class HeroService {
    private headers = new Headers({'Content-Type': 'application/json'});

    ...
    private getHeroesUrl = 'http://localhost:3333/api/heroes';
    constructor(private http: Http) {}

    //this is the method in question
    getHeroes(): Promise<Hero[]> {
        return this.http.get(this.getHeroesUrl).toPromise().then(response => response.json().data as Hero[]).catch(this.handleError);
    }
}

这是Hero模型类:

export class Hero {
    hid: number;
    name: string;
}

这是调用服务的方法的类,并且获取的数组被切片,以及我得到异常的点

export class DashboardComponent implements OnInit {
    heroes: Hero[] = [];
    ...
    ngOnInit(): void {
        this.heroService.getHeroes().then(heroes => this.heroes = heroes.slice(1, 4));
    }
    ...

}

这是异常的完整堆栈跟踪:

Unhandled Promise rejection: Cannot read property 'slice' of undefined ; Zone: angular ; Task: Promise.then ; Value: TypeError: Cannot read property 'slice' of undefined at eval (http://localhost:3000/app/components/dashboard.component.js:22:91) at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:203:28) at Object.onInvoke (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:6242:41) at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:202:34) at Zone.run (http://localhost:3000/node_modules/zone.js/dist/zone.js:96:43) at http://localhost:3000/node_modules/zone.js/dist/zone.js:462:57 at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:236:37) at Object.onInvokeTask (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:6233:41) at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:235:42) at Zone.runTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:136:47) TypeError: Cannot read property 'slice' of undefined at eval (http://localhost:3000/app/components/dashboard.component.js:22:91) at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:203:28) at Object.onInvoke (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:6242:41) at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:202:34) at Zone.run (http://localhost:3000/node_modules/zone.js/dist/zone.js:96:43) at http://localhost:3000/node_modules/zone.js/dist/zone.js:462:57 at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:236:37) at Object.onInvokeTask (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:6233:41) at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:235:42) at Zone.runTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:136:47)

2 个答案:

答案 0 :(得分:4)

in-memory-web-api模块发生了重大变化:

  

截至v0.5.0(2017年10月5日),dataEncapsulation配置   default从false更改为true。 HTTP响应主体持有   数据值直接而不是封装它们的对象   值,{data:...}。这是一个几乎影响所有人的突破性变化   现有的应用程序!

因此,在示例中,请更改此:

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

为:

  getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response => response.json() as Hero[])
      .catch(this.handleError);
  }

答案 1 :(得分:2)

看起来你期望返回一个数组,但数据实际上是一个Object。试试这个

getHeroes(): Promise<Hero[]> {
  return this.http.get(this.getHeroesUrl).toPromise().then(response => response.json().data.heroes as Hero[]).catch(this.handleError);
}

你的英雄数组嵌套在JSON数据结构中的“英雄”键下。