Azure / Azure/azure-functions-nodejs-worker

Table Storage Binding doesn't allow for access or filtering of Table Storage 'Timestamp' property

Open
#320 2 comments 1 reaction 0 assignees View on GitHub
area:nodejs-functions bug investigate P3
Dominant language
TypeScript
Stars
110
Forks
51
Avg merge
1d 1h
Merged PRs (30d)
2

Description

#### Investigative information

Upon retrieving the whole table via my bindings in a function that is triggered on a timer, (see below).
```javascript
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */1 * * * *"
},
{
"name": "eventTable",
"type": "table",
"tableName": "HeartbeatEvents",
"direction": "in"
}
],
"scriptFile": "../dist/src/heartbeat-scheduler/index.js"
}
```
I would expect that the property _Timestamp_ which is a property maintained by the Storage Table server is included in the _eventTable_ binding in the code and be accessible as a property of the array elements of the eventTable, i.e
```typescript
context.bindings.eventTable.forEach((row) => {
context.log(row.Timestamp);
});
```
Instead it is undefined.

In the case of the storage table I am using a very basic set up like so,
![image](https://user-images.githubusercontent.com/8784685/87617141-e6270880-c76a-11ea-9c76-a85be8ed30d8.png)

And when I run the function locally, it is not deployed yet, I get the following output through context logging,

> [16/07/2020 1:51:00 am] Executing 'Functions.heartbeat-scheduler' (Reason='Timer fired at 2020-07-16T13:51:00.0093734+12:00', Id=9972164a-5a33-4f68-a240-95e6b7b6db20)
> [16/07/2020 1:51:00 am] Heartbeat Logging Triggered on: Thu Jul 16 2020 13:51:00 GMT+1200
> [16/07/2020 1:51:00 am] [
> {
> Status: 'received',
> TransactionId: '40574c28-0478-4aeb-a568-40cfea7b957c',
> PartitionKey: 'com.triquestra.cloudevents.salesinvoices.heartbeat',
> RowKey: 'tq-site_code-101'
> },
> {
> Status: 'received',
> TransactionId: '50574c28-0478-4aeb-a568-40cfea7b957c',
> PartitionKey: 'com.triquestra.cloudevents.salesinvoices.heartbeat',
> RowKey: 'tq-site_code-102'
> }
> ]
> [16/07/2020 1:51:00 am] Row 0 has timestamp of: undefined
> [16/07/2020 1:51:00 am] Row 0 has new heartbeat
> [16/07/2020 1:51:00 am] Row 1 has timestamp of: undefined
> [16/07/2020 1:51:00 am] Row 1 has new heartbeat
> [16/07/2020 1:51:00 am] Executed 'Functions.heartbeat-scheduler' (Succeeded, Id=9972164a-5a33-4f68-a240-95e6b7b6db20)
Note how Timestamp is excluded.

As this function is only local at the moment I do not have any function id information yet.

#### Reproduction steps

1. Create a storage table and insert a record (Note that the timestamp field is automatically created and updated)
2. Create a basic timer-triggered application. [(This application was built off the example provided here.)](https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=javascript)
3. Link the storage account associated with the table in your local settings.
4. Try to access the table row's in the timerTrigger function and see that _Timestamp_ is inaccessible.

#### Expected behavior

Expected that _Timestamp_ is accessible for use in the function code.

#### Actual behavior

Any attempts to access _Timestamp_ returns _undefined_.

#### Known workarounds

None known so far. Although I did try adding a _filter_ to the binding to limit by Timestamp and it throws an error. (Accessing other valid properties within the table were fine.)

#### Related information

The function was built in typescript with the only dependency being moment.js. The source for the function is copied below for fast reproduction of the issue.

Source

```typescript
import { AzureFunction, Context } from '@azure/functions';
import moment from 'moment';
import { triggerStartMessage } from '../resources/constants';

const timerTrigger: AzureFunction = async function (
context: Context,
myTimer: any
): Promise {
const now = moment();
const timeStamp = now.toString();
const fifteenMinutesAgo = now.subtract(15, 'minutes');

context.log(triggerStartMessage(timeStamp));
context.log(context.bindings.eventTable);

const checkHeartbeat = (row, index) => {
const isOldHeartbeat = fifteenMinutesAgo.isAfter(row.Timestamp);
context.log(`Row ${index} has timestamp of: ${row.Timestamp}`);
if (isOldHeartbeat) {
context.log(`Row ${index} has old heartbeat`);
} else {
context.log(`Row ${index} has new heartbeat`);
}
}

context.bindings.eventTable.map(checkHeartbeat);
};

export default timerTrigger;
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.