"Converting array into a string in TypeScript/Javascript, but unable to perform operations

After generating a string with the correct structure that includes an array, I am able to navigate through the JSON on sites like

However, when attempting to access the array, it turns out that the array itself is null.

Here is the scenario:

Firstly, the interfaces are defined as follows:

export interface IPlayerJSON {
    idPlayer: number,
    name: string;
    email: string,
    arrayAvatar: Array<IAvatarJSON>,
};

export interface IAvatarJSON {
    idAvatar: number,
    nickName: string,
    original: boolean,
    signature: string,
};

Followed by the overridden method:

public toJSON(): IPlayerJSON {
        let json: IPlayerJSON;
        json = {idPlayer: this.idPlayer, email: this.email, name: this.name, avatarOriginal: this.avatarOriginal.toJSON(),
               arrayAvatar: []}
        for (let r of this.arrayAvatar) {
            json.arrayAvatar.push(r.toJSON());
        };
        return json;
    };

The Avatar object also has a modified toJSON method. The JSON.stringify function generates a correct and navigable JSON output.

However, when trying to rehydrate:

public static playerRehydrate(json: IPlayerJSON): Player {
        let player : Player = new Player(null, null, null);
        console.log('JSON ', json); // Perfect, with an array
        player.setEmail(json.email);
        player.setPlayerID(json.idPlayer);
        player.setName(json.name);
        console.log('Array Avatar ', json.arrayAvatar);
        for (let r of json.arrayAvatar) { // Throws error, length of undefined
            player.addAvatar(RehydrateService.avatarRehydrate(r));
        };
        return player;
    };

The issue arises because json.arrayAvatar is null and interaction with it becomes impossible.

Any suggestions or tips would be greatly appreciated. Thank you!

Answer №1

Oops, I seem to have overlooked a crucial step in the procedure.

Here is the corrected version:

let player: Player;
let txt: string = JSON.stringify(player); // at this point, all the toJSON() functions will be triggered
let playerJSON: IPlayerJSON = JSON.parse(txt); // <-- this line of code was missing
player = playerRehydrate(playerJSON); // now the player object has both state and behavior

Answer №2

The posted code works independently in the playground, indicating that the issue lies elsewhere in your codebase. You may need to check for errors or conflicts in other parts of your project. Unfortunately, I couldn't provide this feedback as a comment due to the length of the playground link with the source code.

interface IPlayerJSON {
    idPlayer: number,
    name: string;
    email: string,
    arrayAvatar: Array<IAvatarJSON>,
}

interface IAvatarJSON {
    idAvatar: number,
    nickName: string,
    original: boolean,
    signature: string,
}

class Avatar {
  constructor(
    public idAvatar: number,
    public nickName: string,
    public original: boolean,
    public signature: string
  ) {

  }
  public toJSON(): IAvatarJSON {
    const { idAvatar, nickName, original, signature } = this;
    return { idAvatar, nickName, original, signature };
  }
}

class Player {
  constructor(
    public idPlayer: number,
    public email: string,
    public name: string,
    public avatarOriginal: Avatar = null,
    public arrayAvatar: Avatar[] = []
  ) {

  }
  public setEmail(email: string) {
    this.email = email;
  }
  public setPlayerID(idPlayer: number) {
    this.idPlayer = idPlayer;
  }
  public setName(name: string) {
    this.name = name;
  }
  public addAvatar(avatar: Avatar) {
    this.arrayAvatar.push(avatar);
  }
  public toJSON(): IPlayerJSON {
    let json: IPlayerJSON;
    json = {
      idPlayer: this.idPlayer, email: this.email, name: this.name,
      // avatarOriginal: this.avatarOriginal.toJSON(), 
      arrayAvatar: []
    }
    for (let r of this.arrayAvatar) {
      json.arrayAvatar.push(r.toJSON());
    };
    return json;
  }
}

class RehydrateService {
    public static playerRehydrate(json: IPlayerJSON): Player {
      let player: Player = new Player(null, null, null);
      console.log('JSON in rehydrate', json); // perfect, with array
      player.setEmail(json.email);
      player.setPlayerID(json.idPlayer);
      player.setName(json.name);
      console.log('Array Avatar in rehydrate', json.arrayAvatar);
      for (let r of json.arrayAvatar) { // throw error, no lenght of undefined
          player.addAvatar(RehydrateService.avatarRehydrate(r));
      };
      return player;
  };
  public static avatarRehydrate(json: IAvatarJSON): Avatar {
    return new Avatar(json.idAvatar, json.nickName, json.original, json.signature);
  }
}

const player: Player = new Player(1, "@", "a",
  new Avatar(2, "b", true, "bb"),
  [
    new Avatar(3, "c", false, "cc"),
    new Avatar(4, "d", false, "dd"),
    new Avatar(5, "e", false, "ee")
  ]
);

console.log("player source:", player)
console.log("player to JSON result:", player.toJSON())
console.log("rehydrate player JSON result:", RehydrateService.playerRehydrate(player.toJSON()))

The last log statement after the toJSON and rehydrate processes now includes the avatar array:

https://i.sstatic.net/RQUhu.png

You can confirm the ability to iterate over the avatar array with the following command:

RehydrateService.playerRehydrate(player.toJSON()).arrayAvatar.forEach(avatar => console.log(avatar))

https://i.sstatic.net/DmhsX.png

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

Deciphering a nested JSON structure using PHP

I have a JSON with nested structure shown below: { "user": { "personal_info": { "name": "XYZ", "State": "CA", "pincode": "12345" }, ...

Tips for extracting information from a JSON response

I'm currently extracting data from a json response, which has the following format. My goal is to retrieve the "recipient" dictionary and display it in a table where each cell contains the name, unique id, and image. How can I extract this dictionary ...

What if there was a magical jQuery method that could automatically trigger a callback function? What could it possibly be named?

Is there a way to load only images and iframes, similar to the .load() function? I want to automatically add a selector element into the "this" variable for this purpose. $('document').ready(function({ $('a').<Something to trigg ...

Preventing Button Click with JQuery Tooltip

I've implemented a JQuery tooltip plugin on my website and it's working great. However, I'm facing an issue where I cannot click on the input button that appears when hovering over the tooltip. It seems like the button is not truly part of t ...

Angular 2: Integrating a service into a class

I am working on an Angular class that represents a shape. My goal is to be able to create multiple instances of this class using a constructor. The constructor requires several arguments that define the properties of the shape. constructor(public center: ...

"Encountered a problem while attempting to download the .xlsx file through http.get in an angular application interfacing

Attempting to download a .xlsx file using Angular 7 and web API in C#, encountering the following error: https://i.sstatic.net/7pwDl.png The code snippet from my service.ts is provided below: public exportExcelFile(matchedRows: string, reportInfoId: num ...

Vue.js with TypeScript: The property 'xxx' is not found on the type 'never'

I have a computed method that I am trying to execute: get dronesFiltered(){ const filtered = this.drones.filter((drone) => { return drone.id.toString().indexOf(this.filterId) > -1 && drone.name.toLowerCase().toString().in ...

Is it possible to customize error messages in @hapi/joi?

Seeking assistance with custom error message overrides in Joi. Consider the schema outlined below. const joiSchema = Joi.object({ name: Joi.string().required(), email: Joi.string().email().required() }) try{ const schema = joiSchema.validateAsyn ...

Converting a 'div' element into a dropdown menu with CSS and Jquery

I am facing a challenge where I have a collection of buttons enclosed in a div that I want to resemble a dropdown: <div id = "group"> <label> Group: </ label> <div value =" 1hour "> 1h < / div> <div value =" 2hou ...

Selecting a default option in Angular when the value is present and repeated

My goal is to pass a parameter in the URL to a page where a select element is populated dynamically. The parameter that needs to be passed is customerProfile.id. I want to find this id in the select options and have it selected by default. How can I achiev ...

The array is arranged properly, yet React is failing to render it in the correct order

Here's the code snippet I am working with: { this.state.rows.map((qc) => qc.BinsByDayByOrchardsQCs.map((qc2) => qc2.BinsByDayByOrchardsQCsDefects.map((qc3) => !defectsArray.includes(qc3.Defect) &am ...

Using Vue.js to mark a checkbox as selected

I've searched extensively and tried various combinations, but I'm unable to initialize my checkboxes as checked. For example: <ul class="object administrator-checkbox-list"> <li v-for="module in modules"> <label v-bin ...

Comparing Ajax HTML with XML/JSON responses: which is better for speed or other considerations

I have a website that heavily relies on ajax, and I insert around 3k html formatted pages into the DOM through ajax requests. My current approach involves inserting the entire html responses using jQuery. However, another option is to output in xml or jso ...

Having trouble obtaining a GuildMember's displayName in Discord.js leads to a TypeError

I'm completely baffled by the situation here. My code is integrated within the Akairo Framework, yet the error seems to be pointing fingers at discord.js itself. Take a look at the error message below: /home/runner/guard/Listeners/automod/nicknames.js ...

Exporting inbound nodes from Keras to JSON format: inbound_nodes

I'm currently trying to wrap my head around how to interpret the JSON representation of a Keras model. The field inbound_nodes stores the inputs for each layer, but I'm puzzled by why they are nested within arrays. For instance, when there are 2 ...

Steer clear of retrieving all the elements from the HTML DOM at once

Scenario I am working on a HTML5+CSS+JS slideshow project that needs to be synchronized across 50 clients in a local area network using a single wireless router. Challenge Due to the heavy content, particularly images, of the slides, I intend to dynamic ...

What is the best approach to slowly transition a value to a different one over a set period of time?

if(!isWalking) { isWalking = true; var animation = setInterval(function () {$player.css({'left': "+="+boxSize/25})}, 10); setTimeout(function(){clearInterval(animation)},250); setTimeout(function(){isWalking = false},250); ...

What is the process for retrieving an attribute from a deserialized nested object?

My JSON file has a specific structure: { "person1": [{"name": "Bobby"}, {"age": 25}, {"height": 178}, {"hobby": "piano"}], "person2": [{"name": "Tyler"}, { "age": 29}, {"height": 185}, {"hobby": "basketball"}], "person3": [{"name": "Mike"}, {" ...

Component loader with dynamic rendering for multiple components

Currently, I am in search of a method to dynamically render components within my Angular application. While exploring various options, I came across the concept of dynamic component loading in Angular (refer to https://angular.io/guide/dynamic-component-lo ...

Modify the form's action attribute when submitted

I am trying to create a form with multiple buttons that will change the action and target properties when a specific button is clicked. Below is my code snippet: <div id="root"> <form :action="form.action" ref="form" :target="form.target"&g ...