如何用Observable填充Angular Mat-Table

时间:2019-05-24 01:49:14

标签: arrays angular observable zero

我正在尝试从AWS DynamoDB表中提取数据并将其显示在Angular Mat-Table中。当我这样做时,即使其中包含12个值,创建的数组也会返回0的长度。我相信这会阻止Mat-Table应用于dataSource更改,并最终显示数据。

控制台结果

Observable {_isScalar: true, _subscribe: ƒ, value: Array(0)}
value: (12) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
_isScalar: true
_subscribe: ƒ (subscriber)
__proto__: Object

组件代码

constructor(private dynamoService: DataDynamoService) {
    let dataSource: Observable<Record[]> = 
this.dynamoService.getAllRecords();
    console.log(dataSource);
}

服务功能代码

getAllRecords(): Observable<Record[]> {
  let dynDoc = {
  TableName: "records-table",
  };

  let retData: Record[] = [];
  Auth.currentCredentials()
    .then(credentials => {
      const dynamoDB = new DynamoDB.DocumentClient({
        credentials: Auth.essentialCredentials(credentials),
        region: 'us-east-1',
      });

      dynamoDB.scan(dynDoc).promise()
        .then(function(data){
          for(let record of data.Items){
            let rec = {
              value1: rec.value1,
              value2: rec.value2,
              value3: rec.value3,
              value4: rec.value4
            }
            retData.push(rec);
           }
        })
  })
  return of(retData);
}

我期望Array(12)的长度,但是收到0

这是最终有效的服务代码:

getAllRecords() {
  let dynDoc = {
    TableName: "my-table-name",
  };

  return Auth.currentCredentials()
    .then(credentials => {
      const dynamoDB = new DynamoDB.DocumentClient({
        credentials: Auth.essentialCredentials(credentials),
        region: 'us-east-1',
      });

      return dynamoDB.scan(dynDoc).promise()
        .then(data => {return of(data.Items);
        })
    })
}

2 个答案:

答案 0 :(得分:0)

retData会在完成承诺后填充,但函数不会等待它。因此它将始终是[]

组件代码

_dataSource: any[] = []; <-- Data bound to mat-table

constructor(private dynamoService: DataDynamoService) {
    this.dynamoService.getAllRecords().then(data => { // <-- value on promise completion
      this._dataSource = data; // <-- set MatTable source to promise values
      console.log(data, this._dataSource);
    });
}

服务代码

getAllRecords(): Promise<Record[]> { // <-- Return a promise, not observable
  let dynDoc = {
  TableName: "records-table",
  };

  let retData: Record[] = [];
  return Auth.currentCredentials() // <--- return outer promise
    .then(credentials => {
      const dynamoDB = new DynamoDB.DocumentClient({
        credentials: Auth.essentialCredentials(credentials),
        region: 'us-east-1',
      });

      return dynamoDB.scan(dynDoc).promise() // <-- return inner promise 
        .then(function(data){
          for(let record of data.Items){
            let rec = {
              value1: rec.value1,
              value2: rec.value2,
              value3: rec.value3,
              value4: rec.value4
            }
            retData.push(rec);
           }

          return retData; // <-- return the data outside the loop, still inside promise
        })
  })
}

模板代码(用于组件)


<mat-table [dataSource]="_dataSource">

...

</mat-table>

如果DynamoDB可以选择使用可观察的对象,我会切换到该选项。

答案 1 :(得分:0)

您可以使用asyncawait来等待诺言。

async getAllRecords(): Observable<Record[]> {
    let dynDoc = {
        TableName: "records-table",
    };
    const credentials = await Auth.currentCredentials();

    const dynamoDB = new DynamoDB.DocumentClient({
        credentials: Auth.essentialCredentials(credentials),
        region: 'us-east-1',
    });

    let retData: Record[] = [];
    const data = await dynamoDB.scan(dynDoc).promise();
    for(let record of data.Items){
        let rec = {
        value1: rec.value1,
        value2: rec.value2,
        value3: rec.value3,
        value4: rec.value4
        }
        retData.push(rec);
    }

    return of(retData);
}

如果dynamoDB.scan(dynDoc)返回“可观察”,则只需使用

async getAllRecords(): Observable<Record[]> {
    let dynDoc = {
      TableName: "records-table",
    };

    const credentials = await Auth.currentCredentials();

    const dynamoDB = new DynamoDB.DocumentClient({
      credentials: Auth.essentialCredentials(credentials),
      region: 'us-east-1',
    });

    return dynamoDB.scan(dynDoc).pipe(
      map(data =>
        data.map(rec => ({
          value1: rec.value1,
          value2: rec.value2,
          value3: rec.value3,
          value4: rec.value4
        }))
      )
    );
}