I have a serialized model which is an object array (associative?) and I need to get and set specific fields within it.

I've tried iterating thru it with jQuery and js, with some limited success, but can only get the 1st level of keys.

{
  "Branch": {
    "ID": 123,
    "Code": "xyz",
    "FkRegionID": null,
    "FkEntityPersonID": null,
    "ParentID": null,
    "Detail": null,
    "Addresses": [],
    "TelephoneNumbers": [],
    "DeletedTelephoneNumbers": [],
    "BankAccounts": [],
  },

  "ParentLookup": null,

  "Address": {
    "ID": 55,
    "FkEntityPersonID": 27,
    "FkEntityAddressTypeID": 1,
    "Address1": null,
    "Address2": null,
    "Address3": null,
    "Address4": null,
    "FkCityID": null,
    "PostalCode": null,
    "CountryID": null,
    "RegionID": null,
    "AddressTypeDetail": null,
    "CityDetail": null
  },

  "AddressCityLookup": null,

  "Telephone": {
    "ID": null,
    "FkEntityPersonID": 27,
    "FkTelephoneTypeID": 1,
    "TelephoneNumber": 0826559999,
    "TelephoneTypeDetail": null
  },
  "TelephoneTypeLookup": null,

}

I'd like to get the value of any of the key value pairs and to set it. e.g. Get the 'BranchCode' of ID=123 and 'code' and set the 'Code' field.

EDIT: This works. The next step is to extract it into it's own array, but that's a different question.

   $.each(serializedObject, function (key, value)
    {
        console.log("key= " + key + "   ." + value);
        if (key == 'Branch')
        {
            value.ID = 456;

            // Get this into a standalone array?
            // newArray
        }
    });

Thanks

1 Answers

0
Vasil Dininski On

You could use the Array.prototype.find (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) method to find the exact element you need and then you can modify it. I.e.

const yourArray = [...];

const targetElement = yourArray.find(function(el){ 
  return el.Branch.ID === '123';
});
targetElement.Branch.code = 'new code';

However if you are targeting older browsers you will need a polyfill for it. As per MDN:

// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    value: function(predicate) {
     // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];

      // 5. Let k be 0.
      var k = 0;

      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. If testResult is true, return kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Increase k by 1.
        k++;
      }

      // 7. Return undefined.
      return undefined;
    },
    configurable: true,
    writable: true
  });
}