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

Getting an input value dynamically in a React variable when there is a change in the input field

I am having an issue with my search text box. I need to extract the value onchange and send a request to an API, but when I try using the normal event.target method, it shows an error. How can I fix this? The problem is that onchange, I need to call a func ...

The functionality of getAttribute has changed in Firefox 3.5 and IE8, no longer behaving as it did before

Creating a JavaScript function to locate an anchor in a page (specifically with, not an id) and then going through its parent elements until finding one that contains a specified class. The code below works perfectly in Firefox 3.0 but encounters issues wi ...

Error encountered while attempting to send a delete request to MongoDB due to connection refusal

Recently, I've been diving into a Next.js tutorial that involves working with MongoDB. Everything seems to be running smoothly when testing my API endpoints with Postman. POST, GET, and DELETE requests all go through without any hiccups. However, thi ...

The promise catch method does not handle JSON parsing correctly

Utilizing Angular's Http to interact with my API has been successful for handling responses with a status of 200. The data is parsed correctly and outputted as expected within the first .then() block. However, when encountering an error with a status ...

Instructions for connecting a button and an input field

How can I connect a button to an input field? My goal is to make it so that when the button is clicked, the content of the text field is added to an array (displayed below) const userTags = []; function addTags(event) { userTags.push(event.target.__ wha ...

Issue with importing React: 'Module not found: Unable to locate'

I've organized my React project with a folder system, as shown in the screenshot below: https://i.stack.imgur.com/Rl9Td.png Currently, I'm attempting to import from context.js, located in src/context.js, into index.js, found in src/components/K ...

PHP is used to download JSON data in mobile applications

My iOS and Android app is designed to download data from a database using JSON and PHP. The process involves numerous mysql queries that retrieve information from my MySQL database. Initially, I created an array in PHP to store all the queries and would ac ...

Error: Cannot iterate over Redux props map as it is not a function

I've encountered an issue while trying to render out a Redux state by mapping through an array of objects. Despite receiving the props successfully, I keep getting an error stating that 'map is not a function'. It seems like the mapping func ...

Navigate the Angular interceptor route to display a 404 error page when clicking on a `<a href="#">` tag

When using href="#" as a placeholder in html, I encountered an issue where Angular was unable to recognize it and would route to the 404 page despite having the following configuration in the module. How can this problem be resolved? .config( function m ...

What is the process for associating JSON reponses with button actions on a webpage?

I developed a JavaScript script that interacts with a Tableau server API to handle running jobs. The script presents the retrieved jobs on a web page, along with corresponding buttons that enable users to terminate specific jobs. While the script function ...

Whenever there is a click event triggered within the map function, it will affect every element within the collection

I am struggling to make changes to a specific item in the map function when clicked. Can someone assist me with achieving this functionality? const Product = ({categories}) => { const [active,setActive] = useState(true) function activeCat ...

Is it permissible for me to incorporate a package from the dependencies listed in the package-lock.json file into my

I'm looking to incorporate date-fns into my project. I currently have react-datepicker, which also uses date-fns. Can I simply utilize date-fns from react-datepicker, or do I need to install it separately in my project? ...

Similar to Laravel's service providers or WordPress style plugins, Node.js has its own unique way of managing and extending functionality

Coming from a PHP/Laravel background, my team is considering using Node.js (and sails) for our upcoming project - a collaboration studio for scholars. However, before making the transition, I am curious about the best practices for creating Laravel-style s ...

The error "TypeError: b.toLowerCase is not a function in the bootstrap typeahead plugin" indicates that

Currently, I am working on implementing autocomplete search using the typeahead plugin version 3.1.1. My implementation involves PHP, MySQL, AJAX, and JavaScript/jQuery. While everything works perfectly with mysqli in terms of displaying suggestions when t ...

The functionality of JQuery ceases to function properly once the BxSlider plugin is activated

I've encountered a strange issue while using the BxSlider plugin of jQuery on my page. When I implement the code for the slider with BxSlider, all other custom functions seem to stop working without any errors being displayed in the console. I've ...

Issue with rendering Base64 image array strings in FlatList component in React Native

In my RN App, I am trying to display a FlatList with Image Items but it seems like I have missed something. I am retrieving blob data from my API, converting it to a String using Buffer, and then adding it to an Array. This Array is used to populate the F ...

Combining ASP.NET Core 2.2 and Angular in a monorepository template for seamless development

The template's default structure has everything in one place, like this: / bin/ obj/ ClientApp/ myproject.csproj Startup.cs etc. In my customized structure, I have multiple libraries and Angular apps - essentially a monorepo - so it requ ...

Is react-particles-js still compatible for me to integrate?

I recently discovered that the package found here: https://www.npmjs.com/package/react-particles-js has been deprecated. Can I still utilize this package? The codes in question can be viewed at: https://codesandbox.io/s/particle-js-background-forked-woypk ...

Operators within an observable that perform actions after a specific duration has elapsed

Is there a way in an rxjs observable chain to perform a task with access to the current value of the observable after a specific time interval has elapsed? I'm essentially looking for a functionality akin to the tap operator, but one that triggers onl ...

What could be causing my Chrome extension to function on Mac but not on a PC?

I created a basic Chrome extension that includes a background page with the following code: <script type="text/javascript> chrome.tabs.onDetached.addListener(function(tabId, info){ var id = tabId; chrome.tabs.get(id, function(tab) { ...