I'm attempting to pull data from an AWS DynamoDB table and display it in an Angular Mat-Table. When I do this, the array created is returning a length of 0 even though there are 12 values in it. I believe this is preventing the Mat-Table from acting on the dataSource change and ultimately displaying the data.
Console Results
Observable {_isScalar: true, _subscribe: ƒ, value: Array(0)}
value: (12) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
_isScalar: true
_subscribe: ƒ (subscriber)
__proto__: Object
Component code
constructor(private dynamoService: DataDynamoService) {
let dataSource: Observable<Record[]> =
this.dynamoService.getAllRecords();
console.log(dataSource);
}
Service function code
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);
}
I expect Array(12) for length, but am receiving 0
This is the service code that ultimately worked:
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);
})
})
}
retData
is filled after the promises are completed, but the function doesn't wait for it. So it will always be []
Component code
_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);
});
}
Service code
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
})
})
}
Template code (for component)
<mat-table [dataSource]="_dataSource">
...
</mat-table>
If DynamoDB has the option to use observables I would switch to that though.