1

I'm trying to loop some products in JSON. I get many different kinds of JSON files and that's why I made form that I can just manually "patch" the file.

{ "product": [ { "@attributes": { "ID": "123456789" }, "name": "Name of the product"],...}

So I have two input fields in my form:

1. id="product_name" value="name"
2. id="product_id" value="['@attributes']['ID']"

I use ng-repeat to loop throug products. These work fine:

{{product}} //Product object
{{product.name}} //name of the product
{{product[value]}} //if value = name, name of the product

My problem is that I don't know how to get that ['@attribute']['ID'] from the product.

EDIT: I know that this will work:

{{product['@attributes']['ID']}}

but I need to change the value from form input.

EDIT: SOLUTION:

controller.getData = function(object, key) {
        var keys = [];
        var count = key.replace(/[^.]/g, '').length;
        if(count === 4){
            keys = key.split(".");
            return object[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]];
        }else if(count === 3){
            keys = key.split(".");
            return object[keys[0]][keys[1]][keys[2]][keys[3]];
        }else if(count === 2){
            keys = key.split(".");
            return object[keys[0]][keys[1]][keys[2]];
        }else if(count === 1){
            keys = key.split(".");
            return object[keys[0]][keys[1]];
        }else{
            return object[key];
        }
    };

New problem:

{ "product": [ 
{ "@attributes": { "ID": "12345" }, 
"name": "productname", 
"price": "xx", 
"URL": "url", 
"images": { "image": "imgUrl" }, 
"description": {}, 
"categories": { 
"category": "Kesäale" }, 
"properties": { "property": [ 
{ "@attributes": { "name": "color" }, "value": "B25 Grisaille" }, 
{ "0": "\n", "@attributes": { "name": "size" } }, 
{ "@attributes": { "name": "currency" }, "value": "EUR" }, 
{ "@attributes": { "name": "brand" }, "value": "brandName" }, 
{ "@attributes": { "name": "fromPrice" }, "value": "xx" }, 
{ "@attributes": { "name": "manufacturer" }, "value": "xx" }, 
{ "@attributes": { "name": "weight" }, "value": "0.5" }, 
{ "@attributes": { "name": "stock" }, "value": "true" }, 
{ "@attributes": { "name": "EAN" }, "value": "1234" } ] }, 
"variations": {} },

How can I get brandName?

0

3 Answers 3

1

This is a problem with some special characters in properties. The same happens if you have a json key like e.g. my-key which cannot be accessed in a property-way. Therefore you can use the fallback array access to get the value:

var x = { "product": [ { "@attributes": { "ID": "123456789" }, "name": "Name of the product"}]}

// [0] not required when looping through the list...
var id = x.product[0]["@attributes"].ID

console.log(id); // 123456789

EDIT: to read it dynamically, you could use some helper function like so (can be extended, if the path is more dynamic)

var key = "@attributes.ID";

function getData(object, key) {
  var keys = key.split(".");
  return object[keys[0]][keys[1]];
}

// sample call for demo purpose
var res = getData(x.product[0], key);
console.log(res);

And call the getData() method from your expression like this:

{{ getData(product, value) }} 

EDIT2: for a fully dynamic structure:

function getDataDyn(object, keystr) {
  var keys = keystr.split(".");
  return digg(object, keys);
}

function digg(obj, keys) {
  if(keys.length === 1) {
    return obj[keys[0]]
  } else {
    return digg(obj[keys[0]], keys.splice(1));    
  }
}

// sample call for demo purpose
var result = getDataDyn(x.product[0], key);
console.log(result);
Sign up to request clarification or add additional context in comments.

4 Comments

Really nice solution :) One more thing. I hate when web shops do this: {"properties": { "property": [ { "@attributes": { "name": "color" }, "value": "B25 Grisaille" }, { "0": "\n", "@attributes": { "name": "size" } }, { "@attributes": { "name": "currency" }, "value": "EUR" }, { "@attributes": { "name": "brand" }, "value": "Halti" } ...} How I can get the value that has the name currency?
Thanks! Would you post a separate question for this problem (and reference this question here)?
Sorry, but I can't post any new topics at the moment.
Okay, saw your update. What is the question? You want to find the object in the list where the @attributes name is "brand" and then read the value? This should be a simple array.map().filter() chain over the property array.
1

You could use {{product['@attributes'].ID}}

Or if the first object key is dynamically named you could do: {{product[Object.keys(product)[0]].ID}}

Object.keys(obj) returns an array of keys for a given object https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

2 Comments

Yes if the JSON file is like that, but if the next one is {{product['@attr'].ID}} it doesn't work. I need something like: {{product[value]}}, but value can't be ['@attr']['ID']
I've updated my answer to access the first key dynamically
0

There are no very elegant solution for this problem. However, you can simplify things significantly if you don't parse key manually and just delegate it to existent Angular services. In your case $parse can already do it.

I would wrap this functionality into custom filter so it could be something like this:

.filter('key', function($parse) {
    return function(context, name) {
        return $parse('this' + name)(context);
    };
});

And them in HTML:

{{ product | key:name }} // name is "['@attributes']['ID']"

Demo: http://plnkr.co/edit/jIIhXDW6S62IYrBXIB94?p=preview

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.