Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have a recursive JavaScript function inside a $.getJSON function?

I have a JSON document of variable depth. An example:

[
    {
        "type": "firsttype",
        "text": {
            "id": "content"
        }
    }
]

What I am trying to do is to retrieve the values of certain keys, say text. Since I do not know where these keys might appear in the .JSON, I need to use a recursive function. I then try to display these keys and values in a HTML file.

I have a preliminary attempt here:

$.getJSON("file.json", function getText (oValue, sKey) {
    links = [];
    if (typeof oValue == "object" || typeof oValue == "array") {
        for (i in oValue) {
            getText (oValue [i], i);
        }
    } else {
        links.push ( "<li id='" + oValue + "'>" + sKey + "</li>" );
    }

    $( "<ul/>", {
        "class": "my-new-list",
        html: links.join( "" )
    }).appendTo( "body" );
});

When I load the page locally or remotely or on python -m SimpleHTTPServer, I get no errors and nothing on the page. What am I doing wrong? I have included all the JS in the $.getJSON call so no async issues arise.

In the future I would also like to include a regexp check so I can extract values with a certain string, e.g. /http/. What would be the best way to do this?

like image 464
Job Chong Avatar asked Nov 09 '22 04:11

Job Chong


1 Answers

As the other answers cover most of the things that you should consider, I think I'll just post a solution for your actual problem. :)

You want to traverse an arbitrary JSON and search for a specific key, and may have a condition on its value. Then you want to return all values for your specified key (that pass your condition if specified).

Consider you have the following json:

{
    "hello": "some text",
    "object": {
        "key1": "hello!",
        "key2": "Bye!"
    },
    "array": [{
        "some_key1": "blah blah blah",
        "some_key2": 24
    }, {
        "some_key1": "ghiojd",
        "some_key2": 13
    }],
    "numeric_array": [2, 3, 4, 5]
}

This snippet will search the above json for some_key1 that its value starts with blah:

function regexpConditionFactory(regex) {
    return function(value) { return regex.test(value); };
}

function searchObjectForKey(obj, key, condition, result) {
    if ($.isPlainObject(obj)) {
        if (obj.hasOwnProperty(key)) {
            if (!condition || ($.isFunction(condition) && condition(obj[key])))
                result.push(obj[key]);
        }
    }

    if ($.isPlainObject(obj) || $.isArray(obj)) {
        for (var k in obj) {
            if (obj.hasOwnProperty(k))
                searchObjectForKey(obj[k], key, condition, result);
        }
    }
}

$.getJSON('file.json', function(data) {
    var res = [];

    searchObjectForKey(data, 'some_key1', regexpConditionFactory(/^blah/), res);

    $('<ul/>', {
        'class': 'my-new-list',
        'html': res.map(function(value) { return '<li>' + value + '</li>'; }).join('')
    }).appendTo('body');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
like image 138
Abbas Mashayekh Avatar answered Nov 14 '22 23:11

Abbas Mashayekh