Dynamically access a JSON element

Asked

Viewed 663 times

1

I have the following JSON:

    [{
    "posts": {
        "ID": 452,
        "post_date": "01\/01\/2016 15:30:00",
        "post_title": "Titulo do post"
    },
    "postmeta": {
        "anexo": {
            "size": {
                "value": "615",
                "unit": "KB"
            },
            "extension": "PDF"
        }
    },
    "taxonomies": {
        "tax_teste": {
            "term_id": 15,
            "name": "minha taxonomia",
            "slug": "minha-taxonomia"
        }
    }
}, {
    "posts": {
        "ID": 34,
        "post_date": "28\/11\/2015 10:13:22",
        "post_title": "Titulo do post2"
    },
    "postmeta": {
        "anexo": {
            "size": {
                "value": "39",
                "unit": "KB"
            },
            "extension": "JPG"
        }
    },
    "taxonomies": {
        "tax_teste": {
            "term_id": 132,
            "name": "taxonomia 2",
            "slug": "taxonomia-2"
        },
        "tax_local": {
            "term_id": 52,
            "name": "Rio de Janeiro",
            "slug": "rio-de-janeiro"
        }
    }
}]

Have an example of HTML:

html = '<table class="tb-widget-materiais">';
html += '<tr class="item_widget item_widget_left">';
html += '<td class="left">';
html += '<a href="{LINK_MATERIAL}" target="_blank" title="{TITLE_MATERIAL}">';
html += '<img width="{WIDTH_IMG}" height="{HEIGHT_IMG}" src="{SRC_IMG}" class="attachment-eiWidgets size-eiWidgets wp-post-image" alt="{TITLE_MATERIAL}" title="{TITLE_MATERIAL}" />';
html += '</a>';
html += '</td>';
html += '<td class="right">';
html += '<p>{DATA_MATERIAL}</p>';
html += '<h3>';
html += '<a href="{LINK_MATERIAL}" target="_blank" title="{TITLE_MATERIAL}">';
html += '{TITLE_MATERIAL} - {SIZE_MATERIAL}</a>';
html += '</h3>';
html += '</td>';
html += '</tr>';
html += '<tr>';
html += '<td>';
html += '<a href="{SLUG_TAXONOMY}">{TAXONOMY}</a>';
html += '</td>';
html += '</tr>';
html += '</table>';

JSON is stored in a variable, I had to decrease to not get too big here in the example, but in the production model there are other elements. I’m having difficulty making a function that takes as parameter this JSON, an HTML and an array with the properties, and performs the exchanges.

ex. call of the function

montaPagina(html,dadosJSON,{"{TITLE_MATERIAL}":"posts.post_title","{SIZE_MATERIAL}":"postmeta.anexo.size.value","{SLUG_TAXONOMY}":"taxonomies.$1.slug","{TAXONOMY}":"taxonomies.$1.name"});

I started creating the function as follows:

montaPagina = function(html,dados,argumentos)
{
    var htmlReturn = '';
    var er = new RegExp(/\[/);
    $.each(dados,function(keyDados,valueDados)
    {
        var htmlTmp = html;

        $.each(argumentos,function(keyArgs,valueArgs)
        {
            var filho = valueArgs.split('.');
            var tmp = valueDados;

            $(filho).each(function(k,v)
            {
                if(er.test(v))
                {
                    vTmp = v.replace(']','');
                    vTmp = vTmp.split('[');
                    tmp = tmp[vTmp[0]];
                    console.log(tmp);
                    /*$(vTmp).each(function(k2,v2)
                    {
                        tmp = tmp[vTmp[0]][v2];
                    });*/

                    //console.log('É array: '+vTmp[0]+"\n\n");
                }else
                {
                    tmp = tmp[v];
                }

                //console.log(tmp);
            });

            console.table(tmp);

            if((typeof tmp !== 'undefined'))
            {
                var regex = new RegExp(keyArgs,"g");
                htmlTmp = htmlTmp.replace(regex,tmp);
            }



        });







       htmlReturn += htmlTmp+"\n\n\n";
    });
    return htmlReturn;
};

But it doesn’t work. If I go straight into the code and type:

var tmp = valueDados.posts.post_title;

I can access the data correctly, but if I try:

var tmp = valueDados.valueArgs;

or

var tmp = valueDados[valueArgs];

or

var tmp = valueDados+"."+valueArgs;

nothing works!

Someone could help me how to solve this?

  • Have you seen the console? Already logged on valueDados to see what’s inside it?

  • So if I give a console only in the Data value, it will return me the object and I can see all the elements, by the console. now if you put any of the options I mentioned above it is an error. If it is the last one it appears. [Object]post.post_title

  • Try logging in valueDados[0].posts.post_title;

  • 2

    Have you ever thought of using a template-like lib Handlebars.js?

  • In javascript array and object have the same behavior, you can manipulate the object name by passing the key as string, example: data[0]["posts"]["ID"] is equal to data[0].posts.ID.

3 answers

0

So I could not. I was able to solve by breaking the request and passing as key, as code below.

paginacaoMontaHTML = function(html,dadosJSON,argumentos)
{
    var htmlReturn = '';
    var er = new RegExp(/\[/);
    $.each(dados,function(keyDados,valueDados)
    {
        var htmlTmp = html;
        $.each(argumentos,function(keyArgs,valueArgs)
        {
            var filho = valueArgs.split('.');
            var tmp = valueDados;

            $(filho).each(function(k,v)
            {
                if(er.test(v))
                {
                    vTmp = v.replace(']','');
                    vTmp = vTmp.split('[');
                    keyVTmp = vTmp[0];
                    vTmp.shift();

                    $(vTmp).each(function(k2,v2)
                    {
                        if(typeof(tmp[keyVTmp]) == 'object')
                        {
                            if(typeof(tmp[keyVTmp][v2]) != 'undefined')
                            {
                                tmp = tmp[keyVTmp][v2];
                            }
                        }
                    });
                }else
                {
                    tmp = tmp[v];
                }
            });

            if((typeof tmp !== 'undefined'))
            {
                var regex = new RegExp(keyArgs,"g");
                htmlTmp = htmlTmp.replace(regex,tmp);
            }
        });
       htmlReturn += htmlTmp+"\n\n\n";
    });
    return htmlReturn;
};

Thank you all very much and I hope that the solution will be useful for other people.

0

The simplest way to solve this is to work with the object itself:

var data = [{
    "posts": {
        "ID": 452,
        "post_date": "01\/01\/2016 15:30:00",
        "post_title": "Titulo do post"
    },
    "postmeta": {
        "anexo": {
            "size": {
                "value": "615",
                "unit": "KB"
            },
            "extension": "PDF"
        }
    },
    "taxonomies": {
        "tax_teste": {
            "term_id": 15,
            "name": "minha taxonomia",
            "slug": "minha-taxonomia"
        }
    }
}, {
    "posts": {
        "ID": 34,
        "post_date": "28\/11\/2015 10:13:22",
        "post_title": "Titulo do post2"
    },
    "postmeta": {
        "anexo": {
            "size": {
                "value": "39",
                "unit": "KB"
            },
            "extension": "JPG"
        }
    },
    "taxonomies": {
        "tax_teste": {
            "term_id": 132,
            "name": "taxonomia 2",
            "slug": "taxonomia-2"
        },
        "tax_local": {
            "term_id": 52,
            "name": "Rio de Janeiro",
            "slug": "rio-de-janeiro"
        }
    }
}];

function getData(collection, key, callResult) {
    if (collection.length > 0) {
       for(var i in collection) {
           callResult(collection[i][key]);
       }
    }
}


var posts = {}

getData(data, 'posts', function(res){
   console.log(res);
    posts = res;
});

console.log(posts)

posts.ID
posts.post_date;
posts.post_title;

-1

Try it this way

var tmp = JSON.parse(valueDados).posts

Browser other questions tagged

You are not signed in. Login or sign up in order to post.