Skip to content

Vandal UI hangs when related data is part of main data in JSON:API response (no 'included' present) #14

Description

@michel3141

Summary

Vandal UI does not correctly resolve relationships when the related resource is already present in the top-level data array, instead of being included in the included section. This behavior causes the UI to hang and fail silently.

Minimal Reproduction

app/models/item.rb

class Item < ApplicationRecord
  belongs_to :previous, class_name: "Item", optional: true
end

app/resources/item_resource.rb

class ItemResource < ApplicationResource
  attribute :label, :string
  attribute :previous_id, :integer

  belongs_to :previous, resource: ItemResource
end

Sample data

a = Item.create(label: "first")
b = Item.create(label: "second", previous: a)

Test case

curl "http://localhost:3000/api/v1/items?include=previous"

Returns:

{
  "data": [
    {
      "id": "1",
      "type": "items",
      "attributes": {
        "label": "first",
        "previous_id": null
      },
      "relationships": {
        "previous": {
          "links": {
            "related": null
          },
          "data": null
        }
      }
    },
    {
      "id": "2",
      "type": "items",
      "attributes": {
        "label": "second",
        "previous_id": 1
      },
      "relationships": {
        "previous": {
          "links": {
            "related": "change_me_in/config/environments:3000/api/v1/items/1"
          },
          "data": {
            "type": "items",
            "id": "1"
          }
        }
      }
    }
  ],
  "meta": {}
}

Proposed Fix

diff --git a/src/response-table.ts b/src/response-table.ts
index 84bbf15..b382d07 100644
--- a/src/response-table.ts
+++ b/src/response-table.ts
@@ -123,7 +123,7 @@ export class ResponseTable {
   private _buildRelationshipNode(jsonRel) {
     let allNodes = this.json.data
     if (!Array.isArray(allNodes)) allNodes = [allNodes]
-    allNodes = allNodes.concat(this.json.included)
+    allNodes = allNodes.concat(this.json.included || [])
     let node = allNodes.filter((n: any) => {
       return n.type === jsonRel.type && n.id === jsonRel.id
     })[0]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions