JSON and Angularjs

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?

Answers


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);

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


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


Need Your Help

SSAS MDX Using IN Function

ssas mdx calculated-field

I have a measure, that's a distinct count on a field in the fact table. I'm now trying to create a calculated member which filters that count based on certain criteria.

Can you Export/Import Flex (4) Data Services?

apache-flex flash-builder connection dataservice

I'm working in flashbuilder 4 (flex4?), and am being asked to create the client-side data services integration 'layer' in a flex app. There is another team working on the actual UI/Presentation. ...