JavaScript's ability to call object properties at multiple levels allows for complex data

My approach involves using mongodb in conjunction with ajax calls for data retrieval. However, I have encountered an issue where the properties needed to generate HTML from JavaScript objects are sometimes missing. Consider this ajax call:

$.ajax({
        url: 'api/v1/mention/'+id,
        type: "GET",
        dataType: "json",
        data : {login : "demo"},
        success: function(mention) {
            display_mention_text(mention.texto);
        }
    });

While calling mention.texto in this case, it could also be mention.picture or any other property. The app crashes when these properties are undefined.

To address this issue, I have created a method that retrieves a property from an object and returns an empty string if it is undefined. Here are some examples of calling this method (the first argument is the object, followed by the properties):

get_property(mention,"text")
get_property(mention,"user","name")
get_property(mention,"picture")

The method is defined as follows:

function get_property(obj){
    var args = Array.prototype.slice.call(arguments),
     obj = args.shift();
    if (checkNested(obj,args)) {
       //what should I do here?
    } else{
                   //the property is undefined and returns ""
        "";
    };
}


    //check if a object has N levels of propertys
function checkNested(obj /*, level1, level2, ... levelN*/) {
  var args = Array.prototype.slice.call(arguments),
      obj = args.shift();

  for (var i = 0; i < args.length; i++) {
    if (!obj.hasOwnProperty(args[i])) {
      return false;
    }
    obj = obj[args[i]];
  }
  return true;
}

In the get_property method, how can I access the property if it does exist? I thought about having the object and its properties stored in an array like: object

params = ["user","name"]

but I cannot access them like this:

object.["user","name"]

Answer №1

Modify the get_property function by replacing the if statement with a for loop borrowed from the checkNested function. Instead of returning true or false, return the discovered value or an empty string "".

function get_property(obj){
    var args = Array.prototype.slice.call(arguments),
        obj = args.shift();

     // Incorporating a 'for' loop in place of the 'if' statement.
    for (var i = 0; i < args.length; i++) {
        if (!obj.hasOwnProperty(args[i])) {
          return "";   // Altered the output of this 'return' statement
        }
        obj = obj[args[i]];
    }
    return obj;  // Adjusted the result of this 'return' statement
}

No new logic was introduced, just a direct copy of your existing code with modifications to the return statements.

Answer №2

To reach your objective, you can follow this approach (without using the checkNested function):

//Parameters    {object, property1, property2, ... propertyN}
function retrieve_property(){
    var args = Array.prototype.slice.call(arguments),
       object = args.shift(),
       property = args.shift();

    if( object.hasOwnProperty(property) ){
        if( args.length > 0 ){
           //Invoke 'retrieve_property' with  {object[property1], property2, ... propertyN} , and so forth
           return retrieve_property.apply(retrieve_property, [object[property]].concat(args));
        }else{
           return object[property];
        }
    }else{
        return "";
    }
}​

Example:

var data = {
    "x" : {
        "y" : 8
    }
};

console.log( retrieve_property(data,"z") );        //  ""
console.log( retrieve_property(data,"x","y") );    //  8
console.log( retrieve_property(data,"x") );        //  {"y":8}

Answer №3

All you need is a straightforward recursive method.

function retrieve_value(object, property) {
    if (object[property]) {
        return object[property];
    }
    else {
        var result;
        for (var key in object) {
            if (object.hasOwnProperty(key)) {
                result = retrieve_value(object[key], property);
            }
        }
        if (!result) {
            // If we reach this point, it means the property doesn't exist at any level
            return;
        }
        else {
            return result;
        }
    }
}

Note: I initially misunderstood your query. Refer to @Engineer's response for accurate information. Leaving this here just in case it proves helpful.

Answer №4

Stop making things more complicated than they need to be. If you already know the structure of your object, simply access it like this:

obj['user']['name'];

If there's a possibility of undefined properties (which usually indicates a larger issue at hand):

let property;
try {
    property = obj.user.name;
} catch (error) {
    property = null;
}

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

Gain access to a variable within an AngularJS directive's scope

I am facing an issue with the following directive var chartDir = function () { return { scope: { stat: '=' }, link: function (scope, element, attr) { console.log(scope); return; } } HTML < ...

What is the best way to end a table row after every group of four items?

I am working with a Handlebars template to display an array of movies in a table with four columns. Currently, I have set up a HBS helper in my code: app.engine('handlebars',exphbs({ defaultLayout: 'main', helpers: { n ...

Deactivate the underscore and include the fiscal year in AngularJS

I am currently faced with a scenario where the back end is returning the value as follows: 123222_D1.123 However, I need to display the date from the database (12-Jun-2020) as 2020-D1.123 in a drop-down menu. Currently, I am displaying the above value i ...

Chaining updateMany() calls in MongoDB while ensuring synchronous response handling

I have encountered an issue while attempting to send 3 separate updateMany requests within a get request, each using a different query. While the first two requests work perfectly, the third updateMany request only functions as expected after refreshing th ...

Running Protractor tests can be frustratingly sluggish and frequently result in timeouts

After spending most of the afternoon struggling with this test, I've tried different approaches but none seem to work. The task at hand is searching for users within the company, generating a table, and selecting the user that matches the name. Curren ...

Establish a WebSocket connection via Meteor.js

How do we establish a Websockets connection in Meteor? Can we achieve this using the following code: ws = new WebSocket('ws://localhost/path'); ws.on('open', function() { ws.send('something'); }); ws.on('message&apo ...

javascript popup appears twice in IE when using PHP

After testing this script on multiple browsers, an issue arises when using IE. In all other browsers, the form submission alert only appears once. However, in Internet Explorer, the alert pops up twice. What could be causing this discrepancy? <!DOCTYP ...

Adding a gradient to enhance an SVG chart

Hey there! I'm currently experimenting with Plotly to create some awesome charts, and I've been trying to figure out how to give my area-charts a gradient instead of the usual fill with opacity. This is how I typically build my graph: Plotly.ne ...

What is the best way to neatly import multiple images in Next.js?

I have a dilemma involving 10 images located in my public directory that I need to use in a component. Instead of individually importing each image like this: import imgurl1 from "../../public/celsius.gif"; import imgurl2 from "../../public/ ...

When using jQuery to enable contenthover on divs, they will now start a new line instead of

I've been working on achieving a layout similar to this, with the contenthover script in action: Mockup Draft Of Desired Look However, the result I'm getting is different from what I expected, it can be seen here. The images are not aligning co ...

I am looking to develop a unique event that can be triggered by any component and listened to by any other component within my Angular 7 application

Looking to create a unique event that can be triggered from any component and listened to by any other component within my Angular 7 app. Imagine having one component with a button that, when clicked, triggers the custom event along with some data. Then, ...

Search for a specific key within a list of dictionaries

I am working with an array of dictionaries: arrayDict: [ { Description: "Dict 0" Category: [ 'First', 'Both', ], }, { Description: ...

Ways to manage an element that has been loaded using the load query function

After implementing the query load function to update posts on the homepage, I was able to display the most up-to-date posts. However, a new issue arose: Whenever I updated all posts without refreshing the entire page, I needed a way to control the element ...

Ways to trigger an event or invoke a function after initializing Stripe JS

My checkout page is optimized with the new Stripe Payment Element for fast loading using SSR. However, I am facing an issue where the element sometimes causes the page to reload 2 or more times before functioning properly. Occasionally, it also displays ...

Sending a request to a JSON file using Ajax

I have 2 questions: 1. I am trying to run this file, but it is not giving any errors or showing results. Please help me identify the problem. 2. I added a dropdown menu in my HTML file, but I'm unsure how to use it to display a list of names. Any sugg ...

Unraveling the Mystery of the JavaScript forEach() Function

Exploring the use of nodejs in Ubuntu and delving into the MDN documentation for the JavaScript forEach() method. While aware of alternative methods, I find that hands-on learning suits me best; my current goal is to create a unique array named copy, conta ...

Looking to enhance my current workaround for utilizing Google Spreadsheet's ImportRange feature

I recently joined this forum and have just started using Google Scripts. I don't have any prior experience with JavaScript or programming languages, but had to learn them when I decided to use Google Apps as the main platform for my small business. M ...

Tips for efficiently updating state within a loop using the settimeout function in a React application

As I work on my react app to visualize sorting algorithms, I've encountered an issue that has me stumped. I am currently iterating through all elements of the array stored in the 'bars' state and attempting to swap them for testing purposes. ...

Retrieve information from a template and pass it to a Vue component instance

Being a newcomer to vue, I have a fundamental question. In my template, I have a value coming from a parsed object prop like this: <h1>{{myval.theme}}</h1> The above code displays the value in the browser. However, I want to store this value i ...

Remove an owl carousel using Laravel, Vue.js, and Axios

I've implemented a sleek slider on my website to showcase images with accompanying text to visitors. The slider utilizes owl carousel within a vue component and is functioning properly. Now, I'm attempting to add a delete button so that users who ...