Warning: The magic method SFML_Singleton::__wakeup() must have public visibility in /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php on line 72

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642
{"id":239,"date":"2018-04-30T09:20:23","date_gmt":"2018-04-30T15:20:23","guid":{"rendered":"http:\/\/www.munderwood.ca\/?p=239"},"modified":"2018-04-30T09:20:23","modified_gmt":"2018-04-30T15:20:23","slug":"what-to-do-if-js-data-serializes-array-elements-as-empty-objects","status":"publish","type":"post","link":"https:\/\/www.munderwood.ca\/index.php\/2018\/04\/30\/what-to-do-if-js-data-serializes-array-elements-as-empty-objects\/","title":{"rendered":"What to do if js-data serializes array elements as empty objects"},"content":{"rendered":"

TL;DR: Use the items<\/span> validation keyword<\/a>\u00a0to specify the data type of the elements of arrays in your js-data schema to avoid unexpected results when serializing records, e.g. for saving.<\/em><\/p>\n

The setup<\/h2>\n

I was using js-data v3<\/a> with a schema containing an array field recently, and came across some initially baffling behaviour. I had a fooSchema<\/span> that included a field definition along these lines:<\/p>\n

import { Schema } from 'js-data';\r\n\r\nconst FooSchema = new Schema({\r\n  \/\/ ...\r\n  barIds: {\r\n    type: 'array',\r\n  },\r\n  \/\/ ...\r\n});\r\n\r\n<\/pre>\n

A\u00a0Foo<\/span>\u00a0object could have many associated Bar<\/span>\u00a0objects, and the API supplying the data specified them by including an array of their integer ids in the barIds<\/span>\u00a0field. Simple enough, and the above worked perfectly while consuming the output of the API. The unexpected behaviour didn’t start until I tried to send the array back to the API to update the record.<\/p>\n

Serializing the array<\/h2>\n

When calling the save<\/span>\u00a0method on a Record<\/span>\u00a0, the defined\u00a0Mapper<\/span>\u00a0serializes it with the toJSON<\/span>\u00a0method. Given the above schema, a record with\u00a0barIds === [2, 3, 5]<\/span>\u00a0 was getting converted to the JSON field\u00a0barIds: [{}, {}, {}]<\/span>. The length of the JSON array was always equal to the length of the underlying data array, but it never contained anything except empty objects instead of the desired relationship information.<\/p>\n

A simple solution<\/h2>\n

When an array field in a record with a schema is serialized by js-data, each element is mapped to an empty object unless a valid JSON Schema<\/a> for the element<\/em> is specified. This choice of defaulting to\u00a0{}<\/span>\u00a0happens in the Schema#pick method<\/a>, when the type<\/span>\u00a0 property of the schema is\u00a0‘array’<\/span>. To prevent this, simply specify the expected schema for the array elements in the schema for the records. In my case since the ids are numbers, this meant:<\/p>\n

import { Schema } from 'js-data';\r\n\r\nconst FooSchema = new Schema({\r\n  \/\/ ...\r\n  barIds: {\r\n    type: 'array',\r\n    items: { type: 'number' },\r\n  },\r\n  \/\/ ...\r\n});<\/pre>\n

The items<\/span>\u00a0validation keyword<\/a>\u00a0specifies how the elements of an array-type property should be treated. If not specified, the default is to treat them as objects. If the array contains actual related elements, then a js-data schema could be given, for example\u00a0bars: BarSchema<\/span>. Otherwise, any valid JSON Schema definition should provide the desired results.<\/p>\n","protected":false},"excerpt":{"rendered":"

TL;DR: Use the items validation keyword\u00a0to specify the data type of the elements of arrays in your js-data schema to avoid unexpected results when serializing records, e.g. for saving. The setup I was using js-data v3 with a schema containing an array field recently, and came across some initially baffling behaviour. I had a fooSchema … [Read more…]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[17],"_links":{"self":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/239"}],"collection":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":10,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":249,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions\/249"}],"wp:attachment":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}