How about converting a bespoke object into a JSON format and then reverting it back to its

While I have come across similar inquiries before, I am still unclear on whether they were answered satisfactorily - perhaps I'm just not grasping it well enough, my apologies.

I am aiming for the convenience and clarity of having my own object named CardboardBox(). This object will solely contain data without any code. My goal is to be able to store this object in a database and retrieve it later, while understanding that it will be classified as type Object() when retrieved. The only method I can think of to determine its original form is:

  1. Include a member variable type that denotes CARDBOARD_BOX
  2. Create a new instance of CarbardBox() and utilize a function within the box to transfer the properties from Object() to the new CardboardBox() object

Is there a more efficient approach to accomplish this task? I believe there might be a way to modify the actual type.

function CardboardBox() { 
  this.type = "CARDBOARD_BOX"
  this.name = "No set";
  this.populate = new function(obj) {
    // populate this object with obj properties 
}

var box = new CarboardBox();  // CarboardBox
box.name = "My Box";
send = JSON.stringyfy(box);   
.
.
.
obj = JSON.parse(send);    // Object

if (obj.type == "CARDBOARD_BOX") {
  savedBox = new CardboardBox();
  savedBox.populate(obj);
}

Thank you in advance... Steve

[edit] Testing Code Below.

function CardboardBox(n) {
  this.name = n;
}

var box = new CardboardBox("My Box");
send = JSON.stringify(box); // JSON CarboardBox()

obj = JSON.parse(send, function fn(obj) { // Object() returned
  log("OB: "+obj.type);
  return obj.type === 'CardboardBox' ? new CardboardBox(obj) : CardboardBox; 
});     
console.log(obj);

Output displayed:

OB: undefined utils.js:40
OB: undefined utils.js:40
function CardboardBox(n) {
    this.name = n;
} 

Answer №1

Here is a potential solution that you can use:

function CardboardBox(n) {
  if(typeof(n) == 'string') {
    //build from name string
    this.name = n;
  } else {
    //build from object
    this.name = n.name;
  }

  //add in this object's "type" in a place
  //that is unlikely to exist in other JSON strings
  this.__type = 'CardboardBox';
}

var box = new CardboardBox("My Box");
send = JSON.stringify(box), // JSON CarboardBox()
obj = JSON.parse(send, function(key, val) {
  //if this is an object, and is CardboardBox
  if(typeof(val) === 'object' && val.__type === 'CardboardBox')
      return new CardboardBox(val);

  return val;

  //or if your object is in a context (like window), and there are many of
  //them that could be in there, you can do:
  //
  //if(typeof(val) === 'object' && context[val.__type])
  //    return new context[val.__type](val);
});


console.log(obj);

This method involves storing the object type in a specific location within the JSON so that it can be easily identified during parsing. If you have multiple objects that need to be instantiated within the same scope, the second parse method provided may be more suitable. It also handles cases where objects in the JSON data are not instances of CarboardBox.

Edit To see this method in action, check out this jsFiddle.

Answer №2

Indeed, it is true that Javascript lacks a built-in mechanism for serializing anything beyond plain objects. As a result, the process of converting data to and from JSON does not maintain class information upon deserialization. Therefore, developers are required to handle serialization and deserialization on their own or utilize a third-party library for assistance.

In my experience, I have found Backbone.js to be quite effective in managing serialization and deserialization tasks. With Backbone.js, one can define a model class with methods for saving data to a server in serialized form and reconstructing the model from serialized data. The crucial aspect here is that deserialization is carried out with knowledge of the specific model being targeted:

  • You can retrieve data from the server based on the model ID by invoking myModel.fetch().
  • To create a new model instance from serialized data, you can use new Model(serializedData).
  • If dealing with multiple models, an array of serialized data can be passed to a collection that understands the model type:
    new ModelCollection(arrayOfSerializedData)
    .

However, Backbone does not offer direct support for casting data of unknown types. In cases where this is necessary, a common approach involves utilizing an intermediary such as a proxy model or factory function, similar to the methodology mentioned in @Chad's response:

var classes = {
    CardboardBox: ...,
    AluminumBox: ...
}

function Deserializer(json) {
    var data = JSON.parse(json),
        type = data.type,
        Cls = classes[type] || DefaultType;
    return new Cls(data);
}

var obj = new Deserializer(send);
obj instanceof CardboardBox; // should yield expected results

It remains essential to incorporate a custom type flag for switching between different data types during deserialization.

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

assign classes to elements with ids falling within a specified range

Looking for an easy method to assign a class to all elements with IDs falling between two specific numbers? For instance, targeting all spans with IDs ranging from 1000 to 2000. Aware that using numbers as IDs wasn't recommended before HTML5. Appre ...

When you click on one checkbox, the angular2-multiselect dropdown automatically selects all the boxes

<angular2-multiselect [data]="sortedDataList | OrderBy : 'clientName'" [(ngModel)]="selectedItem[sortedDataList.clientId]" [settings]="dropdownSettings" name="multiSelect" (onSelect)="onItemSelect($event, ...

What is the best way to test chained function calls using sinon?

Here is the code I am currently testing: obj.getTimeSent().getTime(); In this snippet, obj.getTimeSent() returns a Date object, followed by calling the getTime() method on that Date. My attempt to stub this functionality looked like this: const timeStu ...

Stop initiating the HTTP fetch() requests

Found on Stack Overflow - How can I stop an HTTP fetch() request?, it is now possible to cancel a fetch() request using AbortController. Instead of canceling a fetch() request, I am interested in pausing it temporarily and then resuming it at a later time ...

Dealing with unwanted sorting of x-axis in Plot.ly for R

After numerous attempts, I found myself unable to achieve success. The structure of my data frame is quite straightforward: df <- as.data.frame(matrix(c("g","d","a","b","z",5,4,3,2,1),5,2)) library("plotly") p <- plot_ly(data = df,x = ~V1,y = ~V2,t ...

MongoDB's conditional aggregation function allows users to manipulate and aggregate data based

My mongodb contains data like this: { "_id": "a", "reply": "<", "criterion": "story" }, { "_id": "b", "reply": "<", "criterion": "story" }, { "_id": "c", "reply": ">", "criterion": "story" } What I need is the following result: ...

Can the value of the currently selected option in a select box be obtained without needing to submit the form?

I'm currently working on a project and facing a roadblock with the following task: My goal is to extract the selected value from a dropdown menu and utilize it in my PHP script. The challenge here lies in capturing the chosen option without requirin ...

Querying mongoose with $near or other fields

I'm trying to retrieve documents using a query $or on different fields along with a $near query that is causing issues. Schema locationSchema{ ... beacon: String, access_point: String, gps: [], ... } locationSchema.index({ gps: ...

Using the 'onended' audio event emitter in Angular 2 along with a local member of the Component

I'm looking for assistance on how to utilize audio.onended() in order to play the next song in a playlist. I can successfully add songs to the playlist and play them using the above method with an audioObject. However, when audio.onended triggers, I ...

"Utilizing MongoDB NodeJS Query Logic for Seamless Data Retrieval

Is there a way to implement a logical OR on the same JSON field while querying MongoDB from NodeJS? Here is the current line of code I am using: collection.find({"user":req.user.email, "parent._id":0}, function(err, activities){ if (err) throw err; ...

Manipulating CSS styles through Javascript with passed parameters

I need a feature that allows users to pick the color of the buttons displayed on the website. Currently, I am working with Angular 6 and JavaScript to achieve this functionality. I am focusing on setting the primary color, affecting buttons with the Bootst ...

What is the best way to store objects containing extensive binary data along with additional values?

I'm currently working on saving a JavaScript object that includes binary data along with other values. I want the output to resemble the following: { "value":"xyz", "file1":"[FileContent]", "file2&quo ...

NextJS 13 causes tailwind to malfunction when route group is utilized

I've encountered an issue in my NextJS 13 application where Tailwind classes are no longer being applied after moving page.tsx/layout.tsx from the root directory to a (main) directory within the root. I suspect that there may be a configuration that i ...

Resetting input fields that are not associated with a form in React involves manually setting the values of

In my current project, the user inputs a number or date and month combination along with a year. This input triggers an API call to retrieve information related to the provided input from www.numbersapi.com. The code structure includes components where th ...

WebPack bundling causing issues with Knockout Validation

I am developing a web application using Knockout along with the Knockout-Validation plugin, and I want to utilize WebPack for bundling. However, I encountered an issue where Knockout-Validation seems to break when incorporated with WebPack. To illustrate ...

The node path.relative function is providing inaccurate path information

It seems like there might be an issue with the output of path.relative in Node. When I run the function with 'a/file.js' and 'a/file.css', it returns '../file.css' instead of './file.css'. This is causing confusion f ...

Creating a collapsible navbar using JavaScript

I have implemented a responsive navbar that shrinks with the page size using @media screen. Everything works well, but I need the navbar to collapse into a vertical drop-down menu when the page size is very small, requiring a click to open. Unfortunately, ...

Navigation menu with submenus containing buttons

I attempted to incorporate a dropdown into my existing navigation bar, but unfortunately, the dropdown content disappeared after adding the necessary code. I am now at a loss on how to troubleshoot this issue and make the dropdown function properly. Despit ...

What are some ways I can incorporate modular constants into my Firebase Functions?

While working with Firebase functions, I've come across the option to organize functions into separate files for easier maintenance. You can find the documentation I used here. Currently, I'm exploring how to incorporate modular string constants ...

JQuery experiencing compatibility issues in both Firefox and Chrome

Working on my ASP.NET webpage has presented me with a frustrating problem that I cannot seem to solve. After researching for three days, I have not found anyone who has faced this issue before or offered any solutions. The menu/submenu created using HTML ...