Angular 4 undefined,我相信我缺少一些基本的东西

时间:2018-03-06 02:52:23

标签: angular typescript

所以,我正在开展一个有角度的项目。我正在通过HTTP调用获取数据。

为了验证我做得对,我通常会在控制台上打印出来。当我尝试使用console.log()打印我的结果时,它只适用于我的方法中的对象。当我离开方法的范围时,console.log()不再起作用并打印出没有值的数组。我认为我以错误的方式理解闭包。

无论如何,我真正的问题是我从JSON文件中获取数据并将它们转换为两个独立的数组,然后我尝试合并这两个数组。

以下是我正在使用的服务:

import { Http } from '@angular/http/';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class ManagersService {
  list$;
  contacts$: Array<any>;
  items$;
  nameDatabase: { name: string, id: number  }[] = [] ;
  emailDatabase = [];
  managersList;
// tslint:disable-next-line:max-line-length
private url = ''; 
//I am hidden the URL, because it contains private data,
but it is a complex nested JSON object

  constructor(private http: Http) {


  }

  getList() {
    return this.http.get(this.url)
    .map(response => response.json());
  }


   getManagersNames() {

    this.getList()
    .subscribe(list => {
      this.list$ = list.data;
      //console.log(this.list$);
      for ( const l of this.list$) {
        const managerName = l.attributes.name;
        const managerId = parseInt(l.id);
        const manager = { name: managerName, id: managerId };
        this.nameDatabase.push(manager);
      }



    });
    const x = this.nameDatabase;
    return x;
  }

  checkId() {
    this.getList()
    .subscribe(list => {
      this.contacts$ = list.included;
      console.log(this.contacts$);
      for ( const c of this.contacts$) {
        const managerId = parseInt(c.id) - 1;
        return managerId;
      }
    });
  }

  getManagersContacts() {
    this.getList()
    .subscribe(list => {
      this.contacts$ = list.included;
     // console.log(this.contacts$);
      for ( const c of this.contacts$) {
        if (c.attributes.email) {
          const managerEmail = c.attributes.email;
          const managerId = parseInt(c.id) - 1;
          const manager = { email: managerEmail, id: managerId };
          this.emailDatabase.push(manager);
        } else {
          const managerName = c.attributes.name;
          const managerId = parseInt(c.id);
          const manager = { name: managerName, id: managerId };
          this.nameDatabase.push(manager);
        }
      }

    });
    const y = this.emailDatabase;
    return y;
  }



}

以下是我正在使用的组件:

import { ManagersService } from './../services/managers.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-list-items',
  templateUrl: './list-items.component.html',
  styleUrls: ['./list-items.component.css']
})
export class ListItemsComponent implements OnInit {
// tslint:disable-next-line:max-line-length



constructor(private service: ManagersService) {

  }

  ngOnInit() {
    const x = this.service.getManagersContacts();
    console.log(x);
    const y = this.service.getManagersNames();
    console.log(y);
    const hash = new Map();
    x.concat(y).forEach(function(obj) {
        hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj));
    });
    const finalDatabase = Array.from(hash.values());
    console.log(finalDatabase);
    return finalDatabase;

  }

}

最后,我的app.module.ts:

import { ManagersService } from './services/managers.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';


import { AppComponent } from './app.component';
import { ListItemsComponent } from './list-items/list-items.component';
import { SearchListComponent } from './search-list/search-list.component';
import { DropDownComponent } from './drop-down/drop-down.component';


@NgModule({
  declarations: [
    AppComponent,
    ListItemsComponent,
    SearchListComponent,
    DropDownComponent
  ],
  imports: [
    BrowserModule,
    HttpModule
  ],
  providers: [
    ManagersService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

1 个答案:

答案 0 :(得分:1)

我不确定是否试图回答这个问题,因为没有代码的plunker或stackblitz ...我将获得一个完全正确的类型代码示例的可能性很小。但希望这会让你知道需要做些什么。

首先,建议的经验法则是尽可能使用subscribe尽可能靠近UI。这样,您就可以获得数据检索何时完成的通知,并可以根据需要使用该数据。

其次,要将Http调用中的数据重新格式化/转换为组件所需的格式,请在服务中使用.map而不是.subscribe

<强>服务

该服务看起来像这样:

注意:未检查或验证语法!

  getManagersContacts() {
    this.getList().map(list => {
      this.contacts$ = list.included;
     // console.log(this.contacts$);
      for ( const c of this.contacts$) {
        if (c.attributes.email) {
          const managerEmail = c.attributes.email;
          const managerId = parseInt(c.id) - 1;
          const manager = { email: managerEmail, id: managerId };
          this.emailDatabase.push(manager);
        } else {
          const managerName = c.attributes.name;
          const managerId = parseInt(c.id);
          const manager = { name: managerName, id: managerId };
          this.nameDatabase.push(manager);
        }
      }
    });
    return this.nameDatabase;
  }

<强>组件

组件看起来像这样:

  ngOnInit() {
    const x = this.service.getManagersContacts().subscribe(names => {
                // the data is retrieved at this point, so add any code here
                // inside the subscribe
                console.log(names);
              })
    // your other code
   }