Parsing a Jackson object in JavaScript that includes JsonIdentityInfo

Hey there (excuse my English)

I've been working on an AngularJS front-end website that consumes a web service which produces JSON with Spring MVC. The Spring MVC uses the JsonIdentityInfo option for serialization, so each object is only written once in the JSON and any subsequent references just use an ID. For example, if two "computer" objects are using the same "component", Spring assigns an ID to the first component and the second component just refers to that ID:

[
  {
    "@computerID": 1,
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  },
  {
    "@computerID": 3,
    "component": 2
  }
]

What I need now:

[
  {
    "@computerID": 1,
    "owner" : "Mister B",
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  },
  {
    "@computerID": 3,
    "owner" : "Mister A",
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  }
]

I have searched extensively for code that can achieve this but haven't found anything.

I am unable to modify the web service to change this behavior. Is it possible to edit the JSON on the client side using JavaScript or jQuery (or another library) to replace references with the actual referenced object? (The data structure is quite complex with three levels of subobjects within objects).

Thank you very much.

Answer №1

Just the other day, I encountered a situation very similar to what OP mentioned here. Here's how I tackled it: I leveraged the power of JSOG (Javascript Object Graph) format for the solution.

For the Server Side I incorporated the Jackson-Jsog plugin from https://github.com/jsog/jsog-jackson and added the following annotation to each class:

@JsonIdentityInfo(generator=JSOGGenerator.class)

rather than using

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")

This switch enabled generation in the JSOG format, featuring @id and @ref.

When it comes to the Client Side, utilizing jsog.js is recommended

By making use of the call below, you can convert the JSOG structure into a cyclic one:

cyclicGraph = JSOG.decode(jsogStructure);

Answer №2

Divide all the elements in the array into separate arrays: one for items with a complete component attribute and another for those without. Iterate through the original elements that only have numerical component attributes, then match them with the corresponding @componentID from the "good" array, and perform some copying and moving.

// initializing variables
var final = [], temp = [], bad = [],
    c = {},
    computers = [
      {
        "@computerID": 1,
        "component": {
          "@componentID": 2,
          "processor": 2,
          "ram": "8g",
          "harddrive": "wd"
        }
      },
      {
        "@computerID": 3,
        "component": 2
      }
    ];

// splitting the array into 3 parts: final, bad, & temp
while(computers.length > 0) {
    c = computers.pop();
    if (c.hasOwnProperty("component")) {
        if (typeof c.component === "number") {
            temp.push(c);
        } else {
            final.push(c);
        }
    } else {
        bad.push(c);
    }
}

// looping through temp & finding @componentID within final
while (temp.length > 0) {
    c = temp.pop();
    // checking uniqueness of @componentID 
    var found = getObjects(final, "@componentID", c.component);
    if (found.length) {
        c.component = found[0];
        final.push(c);
    } else {
        bad.push(c);
    }
}


// SOURCE: http://stackoverflow.com/a/4992429/1072176
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}

// resulting in populated arrays: final and/or bad
alert(JSON.stringify(final));

I created three arrays, but ultimately only two are filled: final contains the good new objects, while bad captures objects lacking a component attribute or unable to find a matching @componentID for their component number.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering the parent element's ID in AngularJS: A step-by-step guide

In the below code snippet: angular.element(element).parent() I am trying to figure out how to access the ID of the parent element. I tried using this code: console.log(angular.element(element).parent()) But the console output is as shown below: ...

You are not able to access the instance member in Jest

My first encounter with Javascript has left me puzzled by an error I can't seem to figure out. I'm attempting to extract functions from my class module in order to use them for testing purposes, but they remain inaccessible and the reason eludes ...

Displaying Values/Marks in a Unique Order with Material-UI Slider Component

The default behavior of the Material-UI slider is to display marks/values in ascending order from min to max For instance, if you have a slider configured like this: const marks = [ { value: 1, label: '1' }, { value: 2, lab ...

JavaScript function to convert a string of characters into a readable time format

Is there a way to input a string in an 'input type="time"' field in my HTML code? <label class="item item-input"> <span class="input-label">Departure Time </span> <input type="time" ng-model="heur ...

Troubleshooting Problem with Angular, Laravel, and UI-Router

Currently, I am in the process of developing a Single Page Application (SPA) using AngularJS, Laravel, and UI-Router. In my Laravel routes.php file, there exists a single route '/' that loads index.php - this is where all my dependencies are incl ...

Run a jq command to export data from a JSON file

Below is an example of input json where the keys change dynamically, with the only consistent aspect being the text '_GROUP_NAME' and '_VERSION' [ { "PREPROCESS_GROUP_NAME": "preprocess-group-name", & ...

Incorporating words into the core of a pie chart: Highcharts

Is there a way to display the total value in the center of a pie chart? I've attempted some methods but haven't been successful. The goal is to show the sum of all y values. Input export const data = [ { y: 15, name: "Category 1&q ...

JS: The values printed by setTimeout are always taken from the previous iteration

This issue I'm facing is directly related to JS scope, and despite my efforts in research, I have not been able to find effective solutions from similar stackoverflow queries. Here is the program in question: http://jsfiddle.net/0z525bhf/ function ...

directive unit testing unable to access isolatedScope as it is not recognized as a valid

Currently, I am in the process of conducting unit tests on a directive that was previously created. For my initial test, I simply want to verify a specific variable within the scope of the directive. However, whenever I attempt to execute the method isola ...

Manage the material-ui slider using play and pause buttons in a React JS application

I have a ReactJS project where I am utilizing the continuous slider component from material-ui. My goal is to be able to control the slider's movement by clicking on a play button to start it and stop button to halt it. Below is the code snippet of th ...

When an onClick event is triggered in jQuery, generate a certain number of div blocks based on the available list items, such as image source and heading text

Is it possible to generate input fields dynamically based on a dynamic list with checkboxes, labels, text, images, etc.? I currently have a working solution for checkboxes and labels using the code snippet below: let $checkboxContent = $('.checkboxes ...

Utilizing NGRX reducers with a common state object

Looking for a solution with two reducers: export function reducer1(state: State = initialState,: Actions1.Actions1); export function reducer2(state: State = initialState,: Actions2.Actions1); What I want is for both reducers to affect the same state objec ...

Angular parent scope does not reflect changes when a directive updates the shared scope variable

My directive is designed to validate and modify a specific binded value before triggering the button action. However, I am facing an issue where any updates made to the directive value are not being reflected in the parent scope. Even though I have used (= ...

Easily transform your Twitter Bootstrap menu dropdown to appear on hover instead of click with this simple solution

Is there a way to make the toggle dropdown button display the dropdown menu when hovering over it instead of clicking? I tried using the Bootstrap method $().dropdown('show'). What are your thoughts on this approach? $(document).on("mouseenter ...

Using JavaScript Arrays to Make Labels in Chart.js

I am currently working with Chart.js and have a JavaScript array containing values that look like this: var obj = JSON.parse('{"0":"8.4113","2":"9.5231","3":"9.0655","4":"7.8400"}'); I am passing the "obj" array to my Chart.js, filling out the ...

Caught off guard by this promise: TypeError - Attempting to access a property that does not exist in my Ionic 2 application

I'm encountering an issue with native Facebook login that displays the following error message: Uncaught (in promise): TypeError: Cannot read property 'apply' of undefined I have shared my entire project code below. Although I am able to ...

Ways to stop the location object from resetting in ReactJS when reloading the page

Currently, I am using Link to redirect and call another component. The code looks something like this: <Link to={{ pathname: "/app/" + app.appId, appDetail: { app: app } }}>> When I call the path /app/:appId, it triggers the AppDetails ...

Adjusting the size of icons to fit within a container

I need a div that can display up to 7 icons, depending on certain selections. These icons are from ionicons library. Here is the current code snippet: <div class="item item-text-wrap" style="text-align:center;"> <button class="button" style=" ...

Is there a way to display the most recent time and date from this JSON data on Google Maps?

I am currently developing an application that involves tracking individuals based on their email IDs. I require assistance in displaying a marker on a Google Map to showcase different users and their most recent locations. Although I can parse JSON data, I ...

Issue with CSS transition not displaying ng-show elements properly

I'm currently working on incorporating a fade-in effect for text using the second solution from this source when using ng-show. Here is my HTML setup: <input ng-focus="hasFocus = true" ng-blur="hasFocus = false" type="text" placeholder="Cli ...