mrichar1 / pinia-jsonapi

Use a JSONAPI api with a Pinia store, with data restructuring/normalization. Topics
GNU Affero General Public License v3.0
8 stars 2 forks source link

Not all included models are present in store #3

Closed mdrews21 closed 4 months ago

mdrews21 commented 4 months ago

When making an API call with included key in response, not all models are stored. Example: making a get request the response has data and included keys:

2024-04-22_12h19_45

the jsonapi-store looks now like that:

grafik

So there are several models missing. Why weren't they imported to store?

mrichar1 commented 4 months ago

This is unexpected - the code used in get/post/patch that converts the includes to normalised data and adds it to the store is fairly trivial - so while I would expect it to work or fail completely, to 'half work' is interesting.

Probably the best debugging starting point is to edit node_modules/pinia_jsonapi/src/lib.js in your project and add logging to the getIncludedRecords function as follows:

getIncludedRecords(results) {
    let includes = get(results, ['data', 'included'])
    console.log('INCLUDES: ', includes)
    if (includes) {
      let norm = this.jsonapiToNorm(includes, 'isIncluded')
      console.log('NORM: ', norm)
      return norm
    }
    return {}
  }

That should confirm that the included section in the JSONAPI is as expected, and that it is being normalised correctly.

mdrews21 commented 4 months ago

Thank you for your quick response! Debugging the request gives me this output:

grafik

The store has this content now:

grafik

So some models are missing.

mrichar1 commented 4 months ago

Can you also post the NORM log line value, to confirm if the includes are being correctly normalised or not?

mdrews21 commented 4 months ago

Here we go: NORM log line:

{
    "1": {
        "_jv": {
            "id": 1,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
            },
            "type": "paymenttargets"
        },
        "behavior_on_cost_change": 0,
        "created_at": "2024-04-04 15:15:07",
        "description": null,
        "editable": true,
        "email": "XXX",
        "fax": "XXX",
        "file_path": null,
        "firstname": "XXX",
        "fullname": "XXX",
        "g": "-89.8",
        "ismailed": false,
        "isprinted": false,
        "lastname": "XXX",
        "lowerlimit_g": "-25.0",
        "lowerlimit_lvp": 286032,
        "lowerlimit_price_per_unit": 146683,
        "lvp": 38805,
        "mode": "automatisch",
        "name": "2% 8 Tage, 30 Tage netto",
        "personalnr": 539,
        "price_per_unit": 19900,
        "show_in_quote": true,
        "skontosatz1": "2.0",
        "skontosatz2": "0.0",
        "skontotage1": 8,
        "skontotage1_plus_till_end_of_month": false,
        "skontotage2": null,
        "skontotage2_plus_till_end_of_month": false,
        "state": "OK",
        "state_color": "madang",
        "state_description": "OK",
        "state_icon": "mdiCheckCircle",
        "suggested_g": "2.5",
        "suggested_lvp": 390910,
        "suggested_price_per_unit": 200466,
        "telephone": "05731758843",
        "title": "i.A.",
        "updated_at": "2024-04-04 15:15:07",
        "valid": true,
        "version": 1,
        "zahlungsziel": 30,
        "zahlungsziel_plus_till_end_of_month": false
    },
    "13": {
        "_jv": {
            "id": 13,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/contacts/13"
            },
            "type": "contacts"
        },
        "created_at": "2024-02-01 15:10:13",
        "fax": "XXX",
        "firstname": "XXX",
        "fullname": "XXX",
        "lastname": "XXX",
        "mail": "XXX",
        "telephone": "XXX",
        "title": "Frau",
        "updated_at": "2024-02-01 15:10:13"
    },
    "2": {
        "_jv": {
            "id": 2,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/2"
            },
            "type": "paymenttargets"
        },
        "name": "1% sofort, 3% 14 Tage, 30 Tage netto",
        "skontosatz1": "1.0",
        "skontosatz2": "3.0",
        "skontotage1": 0,
        "skontotage1_plus_till_end_of_month": false,
        "skontotage2": 14,
        "skontotage2_plus_till_end_of_month": false,
        "zahlungsziel": 30,
        "zahlungsziel_plus_till_end_of_month": false
    },
    "3": {
        "_jv": {
            "id": 3,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/customers/3"
            },
            "relationships": {
                "addresses": {
                    "data": [
                        {
                            "attributes": {
                                "city": "Gütersloh",
                                "country": "DE",
                                "country_name": "Deutschland",
                                "distance": 59751,
                                "duration": 2548,
                                "formatted_address": "XXX",
                                "is_billing": true,
                                "is_primary": true,
                                "is_shipping": true,
                                "is_shipping_primary": false,
                                "latitude": "51.91123700",
                                "longitude": "8.39726580",
                                "name1": "XXX",
                                "name2": null,
                                "name3": null,
                                "nonrecurring": false,
                                "post_code": "33332",
                                "reference": "XXX",
                                "street": "XXX"
                            },
                            "id": 4,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/addresses/4"
                            },
                            "type": "addresses"
                        },
                        {
                            "attributes": {
                                "city": "Herford",
                                "country": "DE",
                                "country_name": "Deutschland",
                                "distance": 29950,
                                "duration": 1326,
                                "formatted_address": "XXX",
                                "is_billing": false,
                                "is_primary": false,
                                "is_shipping": true,
                                "is_shipping_primary": false,
                                "latitude": "XXX",
                                "longitude": "8.65177640",
                                "name1": "XXX",
                                "name2": "XXX",
                                "name3": null,
                                "nonrecurring": false,
                                "post_code": "32052",
                                "reference": "XXX",
                                "street": "Röntgenstraße 17"
                            },
                            "id": 5,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/addresses/5"
                            },
                            "type": "addresses"
                        },
                        {
                            "attributes": {
                                "city": "Gütersloh",
                                "country": "DE",
                                "country_name": "Deutschland",
                                "distance": 59751,
                                "duration": 2548,
                                "formatted_address": "XXX",
                                "is_billing": false,
                                "is_primary": false,
                                "is_shipping": true,
                                "is_shipping_primary": true,
                                "latitude": "XXX",
                                "longitude": "8.39726580",
                                "name1": "XXX",
                                "name2": "XXX",
                                "name3": "XXX",
                                "nonrecurring": false,
                                "post_code": "XXX",
                                "reference": "XXX",
                                "street": "XXX"
                            },
                            "id": 6,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/addresses/6"
                            },
                            "type": "addresses"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/customers/3/addresses",
                        "self": "http://127.0.0.1:8000/api/v1/sales/customers/3/relationships/addresses"
                    }
                },
                "contacts": {
                    "data": [
                        {
                            "id": 17,
                            "type": "contacts"
                        },
                        {
                            "id": 18,
                            "type": "contacts"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/customers/3/contacts",
                        "self": "http://127.0.0.1:8000/api/v1/sales/customers/3/relationships/contacts"
                    }
                },
                "products": {
                    "data": [
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/customers/3/products",
                        "self": "http://127.0.0.1:8000/api/v1/sales/customers/3/relationships/products"
                    }
                },
                "remarks": {
                    "links": [
                    ]
                },
                "termofpayment": {
                    "data": {
                        "id": 1,
                        "type": "termofpayments"
                    },
                    "links": [
                    ]
                }
            },
            "type": "customers"
        },
        "created_at": "2024-02-01 15:10:13",
        "name": "XXX",
        "primary_address_text": "XXX",
        "shortname": "XXX",
        "updated_at": "2024-02-09 14:07:27"
    },
    "4": {
        "_jv": {
            "id": 4,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/employees/4"
            },
            "type": "employees"
        },
        "email": "XXX",
        "fax": "XXX",
        "firstname": "XXX",
        "fullname": "XXX",
        "lastname": "XXX",
        "personalnr": 535,
        "telephone": "XXX",
        "title": null
    },
    "6": {
        "_jv": {
            "id": 6,
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/contents/6"
            },
            "relationships": {
                "quote": {
                    "links": [
                    ]
                },
            },
            "type": "contents"
        },
        "category": 2,
        "created_at": "2024-02-09 14:50:46",
        "editable": true,
        "updated_at": "2024-02-09 14:50:46"
    },
    "pr24-9v7h": {
        "_jv": {
            "id": "pr24-9v7h",
            "isIncluded": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h"
            },
            "no": "PR24-9V7H",
            "no_slug": "pr24-9v7h",
            "relationships": {
                "amounts": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/amounts",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/amounts"
                    }
                },
                "components": {
                    "data": [
                        {
                            "id": 1,
                            "type": "components"
                        },
                        {
                            "id": 2,
                            "type": "components"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/components",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/components"
                    }
                },
                "contents": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/contents",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/contents"
                    }
                },
                "processings": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/processings",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/processings"
                    }
                },
                "producttype": {
                    "data": {
                        "id": 1,
                        "type": "producttypes"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/producttype",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/producttype"
                    }
                },
                "quoteproducts": {
                    "data": [
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/quoteproducts",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/quoteproducts"
                    }
                },
                "quotes": {
                    "data": [
                        {
                            "attributes": {
                                "description": "Hallo We"
                            },
                            "id": 4,
                            "no": "AN24-0004",
                            "no_slug": "an24-0004",
                            "type": "quotes"
                        }
                    ],
                    "links": [
                    ]
                },
                "tags": {
                    "data": [
                        {
                            "attributes": {
                                "created_at": "2024-02-01 15:17:35",
                                "name": "Rückstichheftung",
                                "order_column": 1,
                                "slug": "ruckstichheftung",
                                "updated_at": "2024-02-01 15:17:35"
                            },
                            "id": 1,
                            "links": [
                            ],
                            "type": "tags"
                        },
                        {
                            "attributes": {
                                "created_at": "2024-02-01 15:17:35",
                                "name": "A4",
                                "order_column": 2,
                                "slug": "a4",
                                "updated_at": "2024-02-01 15:17:35"
                            },
                            "id": 2,
                            "links": [
                            ],
                            "type": "tags"
                        },
                        {
                            "attributes": {
                                "created_at": "2024-02-01 15:17:35",
                                "name": "Bilderdruck",
                                "order_column": 3,
                                "slug": "bilderdruck",
                                "updated_at": "2024-02-01 15:17:35"
                            },
                            "id": 3,
                            "links": [
                            ],
                            "type": "tags"
                        },
                        {
                            "attributes": {
                                "created_at": "2024-02-01 15:17:35",
                                "name": "Dispersionslack",
                                "order_column": 4,
                                "slug": "dispersionslack",
                                "updated_at": "2024-02-01 15:17:35"
                            },
                            "id": 4,
                            "links": [
                            ],
                            "type": "tags"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/tags",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/tags"
                    }
                },
                "unit_costs": {
                    "data": {
                        "attributes": {
                            "name": "Stück",
                            "name_plural": "Stück",
                            "shortname": "Expl."
                        },
                        "id": 1,
                        "type": "units"
                    },
                    "links": [
                    ]
                },
                "variables": {
                    "data": [
                        {
                            "id": 26,
                            "type": "variables"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/variables",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/variables"
                    }
                },
                "variants": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/variants",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/variants"
                    }
                },
                "workflows": {
                    "data": [
                        {
                            "id": 2,
                            "type": "workflows"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/workflows",
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/workflows"
                    }
                }
            },
            "type": "products"
        },
        "created_at": "2024-02-01 15:52:34",
        "description": "XXX",
        "multiplier_cost": 1000,
        "name": "XXX",
        "state": "OK",
        "state_color": "madang",
        "state_description": "Das Produkt ist korrekt kalkuliert und kann produziert werden",
        "state_icon": "mdiCheckCircle",
        "template": false,
        "updated_at": "2024-02-01 15:54:11"
    }
}

As you can see there are attributes in the first object, that doesn't belong to it. Seems like the missing models attributes are all mapped to this first object. The other objects seem to be OK.

grafik

mrichar1 commented 4 months ago

Thanks for posting that output - this has allowed me to track down a bug in the code and squash it.

The issue is that the code assumed that when handling an array of objects from the API, they were all of the same type. This is true for the main records, but not for includes. I hadn't noticed this as all my projects use UUIDs, and the test suite didn't include 2 objects with the same id but different types.

I've updated the code to handle includes properly, so records aren't being 'merged' if they share an ID, and updated the tests to check this works. I've published a new version: 6.5.0 which should be on npm.

Let me know if that works for you, and thanks for reporting!

mdrews21 commented 4 months ago

Thank you for your update. It is now working and every object in included is merged correctly!