UTC Timezone handling does not apply to subtables

Wappler Version : 5.3.1
Operating System : mac
Server Model: node
Database Type: mysql
Hosting Type: docker

Expected behavior

When setting Timezone Handling to UTC, datetime values should be always returned in the ISO 8601 notation.

Actual behavior

If a datetime column is queried as part of a subtable, the datetime is returned as local rather than as UTC

How to reproduce

Create a query that utilizes a subtable and has datetime/ts columns:

Note the difference in created_at values in the dev console. The primary table works, but the subtable does not

Screenshot 2023-01-11 at 10.59.31 AM

Ouch. Trying to debug that would be painful

There is a similar problem if use a database paged query

Could you test with this update: dbconnector.zip (3.4 KB)

Thanks Patrick, but no luck.

Driver dependent mode:
Screenshot 2023-01-16 at 7.38.39 AM

UTC:
Screenshot 2023-01-16 at 7.38.19 AM

For the conversion I depend on the metadata that Wappler adds to the action, can you share the json of the action step.

I’ve updated some code that will try to detect dates in the output when no metadata is available.
app.zip (5.3 KB) Unzip to lib/core.

Thanks Patrick.

Here is the response when using the revised app.zip

{"status":"500","message":"obj is not defined","stack":"ReferenceError: obj is not defined\n    at formatRecord (/opt/node_app/lib/core/app.js:352:60)\n    at Object.options.postProcessResponse (/opt/node_app/lib/core/app.js:392:24)\n    at Client_MySQL2.postProcessResponse (/opt/node_app/node_modules/knex/lib/client.js:164:26)\n    at /opt/node_app/node_modules/knex/lib/execution/runner.js:135:51\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Runner.ensureConnection (/opt/node_app/node_modules/knex/lib/execution/runner.js:300:14)\n    at async Runner.run (/opt/node_app/node_modules/knex/lib/execution/runner.js:30:19)\n    at async App._exec (/opt/node_app/lib/core/app.js:599:30)\n    at async App._exec (/opt/node_app/lib/core/app.js:566:17)\n    at async App.exec (/opt/node_app/lib/core/app.js:535:9)"}

And here is the action json:

{
        "name": "qry_message_thread",
        "module": "dbconnector",
        "action": "single",
        "options": {
          "connection": "db",
          "sql": {
            "type": "SELECT",
            "columns": [
              {
                "table": "message_threads",
                "column": "message_thread_id"
              },
              {
                "table": "message_threads",
                "column": "creator_user_id"
              },
              {
                "table": "message_threads",
                "column": "thread_name"
              },
              {
                "table": "message_threads",
                "column": "created_at"
              },
              {
                "table": "message_threads",
                "column": "thread_type"
              }
            ],
            "params": [
              {
                "operator": "equal",
                "type": "expression",
                "name": ":P1",
                "value": "{{$_GET.message_thread_id}}",
                "test": ""
              },
              {
                "operator": "equal",
                "type": "expression",
                "name": ":P2",
                "value": "{{identity}}",
                "test": ""
              }
            ],
            "table": {
              "name": "message_threads"
            },
            "primary": "message_thread_id",
            "joins": [
              {
                "table": "message_thread_users",
                "column": "*",
                "type": "INNER",
                "clauses": {
                  "condition": "AND",
                  "rules": [
                    {
                      "table": "message_thread_users",
                      "column": "message_thread_id",
                      "operator": "equal",
                      "value": {
                        "table": "message_threads",
                        "column": "message_thread_id"
                      },
                      "operation": "="
                    }
                  ]
                },
                "primary": "message_thread_user_id"
              }
            ],
            "sub": {
              "messages": {
                "type": "SELECT",
                "table": {
                  "name": "messages",
                  "alias": "messages"
                },
                "key": "message_thread_id",
                "columns": [
                  {
                    "table": "messages",
                    "column": "message_id"
                  },
                  {
                    "table": "messages",
                    "column": "created_at"
                  },
                  {
                    "table": "messages",
                    "column": "modified_at"
                  },
                  {
                    "table": "messages",
                    "column": "creator_user_id"
                  },
                  {
                    "table": "messages",
                    "column": "message_text"
                  },
                  {
                    "table": "message_creators",
                    "column": "first_name"
                  },
                  {
                    "table": "message_creators",
                    "column": "last_name"
                  },
                  {
                    "table": "message_creators",
                    "column": "avatar"
                  },
                  {
                    "table": "messages",
                    "column": "message_type"
                  },
                  {
                    "table": "message_creators",
                    "column": "full_name"
                  }
                ],
                "params": [],
                "primary": "message_id",
                "joins": [
                  {
                    "table": "users",
                    "column": "*",
                    "alias": "message_creators",
                    "type": "INNER",
                    "clauses": {
                      "condition": "AND",
                      "rules": [
                        {
                          "table": "message_creators",
                          "column": "user_id",
                          "operator": "equal",
                          "value": {
                            "table": "messages",
                            "column": "creator_user_id"
                          },
                          "operation": "="
                        }
                      ]
                    },
                    "primary": "user_id"
                  }
                ],
                "query": "SELECT messages.message_id, messages.created_at, messages.modified_at, messages.creator_user_id, messages.message_text, message_creators.first_name, message_creators.last_name, message_creators.avatar, messages.message_type, message_creators.full_name\nFROM messages AS messages\nINNER JOIN users AS message_creators ON message_creators.user_id = messages.creator_user_id"
              },
              "members": {
                "type": "SELECT",
                "table": {
                  "name": "message_thread_users",
                  "alias": "users"
                },
                "key": "message_thread_id",
                "columns": [
                  {
                    "table": "users",
                    "column": "message_thread_user_id"
                  },
                  {
                    "table": "users",
                    "column": "created_at"
                  },
                  {
                    "table": "users",
                    "column": "modified_at"
                  },
                  {
                    "table": "users",
                    "column": "user_id"
                  },
                  {
                    "table": "users",
                    "column": "role"
                  },
                  {
                    "table": "member_users",
                    "column": "first_name"
                  },
                  {
                    "table": "member_users",
                    "column": "last_name"
                  },
                  {
                    "table": "member_users",
                    "column": "avatar"
                  },
                  {
                    "table": "member_users",
                    "column": "full_name"
                  }
                ],
                "params": [],
                "primary": "message_thread_user_id",
                "joins": [
                  {
                    "table": "users",
                    "column": "*",
                    "alias": "member_users",
                    "type": "INNER",
                    "clauses": {
                      "condition": "AND",
                      "rules": [
                        {
                          "table": "member_users",
                          "column": "user_id",
                          "operator": "equal",
                          "value": {
                            "table": "users",
                            "column": "user_id"
                          },
                          "operation": "="
                        }
                      ]
                    },
                    "primary": "user_id"
                  }
                ],
                "query": "SELECT users.message_thread_user_id, users.created_at, users.modified_at, users.user_id, users.role, member_users.first_name, member_users.last_name, member_users.avatar, member_users.full_name\nFROM message_thread_users AS users\nINNER JOIN users AS member_users ON member_users.user_id = users.user_id\nWHERE users.status = 'active'\nORDER BY users.role ASC, member_users.last_name ASC",
                "wheres": {
                  "condition": "AND",
                  "rules": [
                    {
                      "id": "users.status",
                      "field": "users.status",
                      "type": "string",
                      "operator": "equal",
                      "value": "active",
                      "data": {
                        "table": "users",
                        "column": "status",
                        "type": "text",
                        "columnObj": {
                          "type": "enum",
                          "enumValues": [
                            "active",
                            "removed_self"
                          ],
                          "default": "'active'",
                          "maxLength": 12,
                          "primary": false,
                          "nullable": true,
                          "name": "status"
                        }
                      },
                      "operation": "="
                    }
                  ],
                  "conditional": null,
                  "valid": true
                },
                "orders": [
                  {
                    "table": "users",
                    "column": "role",
                    "direction": "ASC",
                    "recid": 1
                  },
                  {
                    "table": "member_users",
                    "column": "last_name",
                    "direction": "ASC",
                    "recid": 2
                  }
                ]
              }
            },
            "wheres": {
              "condition": "AND",
              "rules": [
                {
                  "id": "message_threads.message_thread_id",
                  "field": "message_threads.message_thread_id",
                  "type": "double",
                  "operator": "equal",
                  "value": "{{$_GET.message_thread_id}}",
                  "data": {
                    "table": "message_threads",
                    "column": "message_thread_id",
                    "type": "number",
                    "columnObj": {
                      "type": "increments",
                      "primary": true,
                      "nullable": false,
                      "name": "message_thread_id"
                    }
                  },
                  "operation": "="
                },
                {
                  "id": "message_thread_users.user_id",
                  "field": "message_thread_users.user_id",
                  "type": "double",
                  "operator": "equal",
                  "value": "{{identity}}",
                  "data": {
                    "table": "message_thread_users",
                    "column": "user_id",
                    "type": "number",
                    "columnObj": {
                      "type": "reference",
                      "primary": false,
                      "nullable": false,
                      "references": "user_id",
                      "inTable": "users",
                      "referenceType": "integer",
                      "onUpdate": "NO ACTION",
                      "onDelete": "NO ACTION",
                      "name": "user_id"
                    }
                  },
                  "operation": "="
                }
              ],
              "conditional": null,
              "valid": true
            },
            "query": "SELECT message_threads.message_thread_id, message_threads.creator_user_id, message_threads.thread_name, message_threads.created_at, message_threads.thread_type\nFROM message_threads\nINNER JOIN message_thread_users ON message_thread_users.message_thread_id = message_threads.message_thread_id\nWHERE message_threads.message_thread_id = :P1 /* {{$_GET.message_thread_id}} */ AND message_thread_users.user_id = :P2 /* {{identity}} */"
          }
        },
        "meta": [
          {
            "name": "members",
            "type": "array",
            "sub": [
              {
                "type": "text",
                "name": "first_name"
              },
              {
                "type": "text",
                "name": "last_name"
              }
            ]
          },
          {
            "name": "messages",
            "type": "array",
            "sub": [
              {
                "type": "text",
                "name": "first_name"
              },
              {
                "type": "text",
                "name": "last_name"
              }
            ]
          }
        ],
        "outputType": "object",
        "type": "dbconnector_single",
        "output": true
      }

Seems I forgot to change a parameter there, did copy/paste part of the code from an other location. Have it fixed here: app.zip (5.3 KB)

Seeing your json it seems that the metadata is not complete, we will look into that issue. Let me know if the updated file above solves your problem, it will try to detect the date fields when the metadata is missing like in your case.

Thanks, that takes care of it!

Not sure this is relevant, as I have not run into this (yet), but wouldn’t your fix also help nested data from a custom query?

It should fix date formatting in all database queries.

The update didn’t make it in yesterdays Wappler update. We are still checking the issue with the metadata.

Does the data picker allow you to pick all the data from the server action? Perhaps you can open the server action in Wappler and save it again to see if it then updates the metadata.

If it doesn’t update the meta data,could you then restart Wappler with Logging and then try again saving that server action and send us the log file.

All seems fine in the picker

report1674233936542.zip (589.4 KB)

Fixed in Wappler 5.3.3

This topic was automatically closed after 2 days. New replies are no longer allowed.