Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON @attributes and @association levels with js and / or angularjs

I'm currently working on a project that uses an API to retrieve, update and delete data. The API i'm using is the prestashop API. So after being able to retrieve data and update some items i stumbled upon an issue. As told in the documentation all data sent and retrieved through the API is with json and xml Since some data of the API has different levels in the json return like the @attributes and @associations levels i came up with this question.

The thing is I would like to access this data and, in combination with angularjs I would like to show this data. So let me show you a quick example of what I'm trying to achieve.

First of all the JSON return would be something like this.

{"products":{"product":[{"id":"1","id_manufacturer":"1","id_supplier":"1","id_category_default":"5","new":{},"cache_default_attribute":"1","id_default_image":"1","id_default_combination":"1","id_tax_rules_group":"1","position_in_category":"0","manufacturer_name":"Fashion Manufacturer","quantity":"0","type":"simple","id_shop_default":"1","reference":"demo_1","supplier_reference":{},"location":{},"width":"0.000000","height":"0.000000","depth":"0.000000","weight":"0.000000","quantity_discount":"0","ean13":"333456789111","isbn":{},"upc":{},"cache_is_pack":"0","cache_has_attachments":"0","is_virtual":"0","state":"1","on_sale":"0","online_only":"0","ecotax":"0.000000","minimal_quantity":"1","price":"16.510000","wholesale_price":"4.950000","unity":{},"unit_price_ratio":"0.000000","additional_shipping_cost":"0.00","customizable":"0","text_fields":"0","uploadable_files":"0","active":"1","redirect_type":"404","id_type_redirected":"0","available_for_order":"1","available_date":"0000-00-00","show_condition":"0","condition":"new","show_price":"1","indexed":"1","visibility":"both","advanced_stock_management":"0","date_add":"2017-03-16 14:36:24","date_upd":"2017-12-01 13:01:13","pack_stock_type":"3","meta_description":{"language":{"@attributes":{"id":"1"}}},"meta_keywords":{"language":{"@attributes":{"id":"1"}}},"meta_title":{"language":{"@attributes":{"id":"1"}}},"link_rewrite":{"language":"gebleekte-T-shirts-met-korte-mouwen"},"name":{"language":"Gebleekte T-shirts met Korte Mouwen"},"description":{"language":"
Fashion maakt goed ontworpen collecties sinds 2010. Het merk biedt vrouwelijke combineerbare kleding en statement dresses en heeft een pr\u00eat-\u00e0-porter collectie ontwikkeld met kledingstukken die niet in een garderobe mogen ontbreken. Het resultaat? Cool, gemakkelijk, easy, chique met jeugdige elegantie en een duidelijk herkenbare stijl. Alle prachtige kledingstukken worden met de grootste zorg gemaakt in Itali\u00eb. Fashion breidt zijn aanbod uit met accessoires zoals schoenen, hoeden, riemen!<\/p>"},"description_short":{"language":"

Gebleekt T-shirt met korte mouwen en hoge halslijn. Zacht en elastisch materiaal zorgt voor een comfortabele pasvorm. Maak het af met een strooien hoed en u bent klaar voor de zomer!<\/p>"},"available_now":{"language":"Op voorraad"},"available_later":{"language":{"@attributes":{"id":"1"}}},"associations":{"categories":{"@attributes":{"nodeType":"category","api":"categories"},"category":[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]},"images":{"@attributes":{"nodeType":"image","api":"images"},"image":[{"id":"1"},{"id":"2"},{"id":"3"},{"id":"4"}]},"combinations":{"@attributes":{"nodeType":"combination","api":"combinations"},"combination":[{"id":"1"},{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"},{"id":"6"}]},"product_option_values":{"@attributes":{"nodeType":"product_option_value","api":"product_option_values"},"product_option_value":[{"id":"1"},{"id":"13"},{"id":"14"},{"id":"2"},{"id":"3"}]},"product_features":{"@attributes":{"nodeType":"product_feature","api":"product_features"},"product_feature":[{"id":"5","id_feature_value":"5"},{"id":"6","id_feature_value":"11"},{"id":"7","id_feature_value":"17"}]},"tags":{"@attributes":{"nodeType":"tag","api":"tags"}},"stock_availables":{"@attributes":{"nodeType":"stock_available","api":"stock_availables"},"stock_available":[{"id":"1","id_product_attribute":"0"},{"id":"11","id_product_attribute":"1"},{"id":"12","id_product_attribute":"2"},{"id":"13","id_product_attribute":"3"},{"id":"22","id_product_attribute":"4"},{"id":"23","id_product_attribute":"5"},{"id":"24","id_product_attribute":"6"}]},"accessories":{"@attributes":{"nodeType":"product","api":"products"}},"product_bundle":{"@attributes":{"nodeType":"product","api":"products"}}}},

The structure simplified

products {
product {
        id:
        name:
        category:
        ...
        @attributes {
            id:
            language:
            ...
        }
        @attributes {
            {"nodeType":"product_option_value","api":"product_option_values"},"product_option_value":[
                {"id":"1"},
                {"id":"11"},
                {"id":"8"}, 
                {"id":"2"},
                {"id":"3"}
                ]
            },
        }
    }
}

Using the $http.get() function in Angularjs I'm able to retrieve the data and use an ng-repeat and bind combination to show the product_names. Now I would like to access the @attribute values and so on. But how would I be able to access them? Is there a specific way to do this? or is it purely done by accessing the depth level of the JSON object?

The AngularJS function for the products:

$http.get('config/get/getProducts.php', {cache: true}).then(function (response) {
        $scope.products = response.data.products.product
    });

Then in the <html> I can simply use:

<div ng-if="product.active == 1" class="productimg col-4" ng-repeat="product in products | filter : {id_category_default: catFilter.id}: true | filter:productSearch | filter:product.name | orderBy: 'name'">
    <p ng-bind="product.name.language"></p>
</div>

UPDATE: 01/02/2018 So after reading and testing some of the comments i've come up with a reasonable solution. I'm able to access the @attributes and associations values but i've stumbled upon a new problem. The return i'm getting for each filter are multiple "id" values. Take a look at the example below.

<div class="col-lg-3" ng-repeat="value in products">
    <p ng-bind="value.associations.categories.category"></p>
</div>

Returns:

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"7"}]

Where each row of [ .. .. ] stands for a different product. Now i need to get these values as only the numbers that they are so that i can compare them with corresponsding id values from different tables. A good result would be:

2, 3, 4, 5

The question is how would i be able to get to this solution?

If anyone is interested in why and how. I'm trying to retrieve the option_values id's and category id's from the products from a prestashop installation, and all that through the prestashop webservice.

like image 337
Deathstorm Avatar asked Dec 18 '17 10:12

Deathstorm


People also ask

How to set http request header in AngularJS?

To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults. headers. get = { 'My-Header' : 'value' } .

What is property in JSON?

A JSON object contains zero, one, or more key-value pairs, also called properties. The object is surrounded by curly braces {} . Every key-value pair is separated by a comma. The order of the key-value pair is irrelevant.


2 Answers

As I understand you would like to use ng-repeat with nested JSON objects. You will need to use more than one repeater because a single repeated item can contain multiple items of its own which you would like to display.

So as far as I can see something like this should work:

<div ng-if="product.active == 1" class="productimg col-4" ng-repeat="product in products | filter : {id_category_default: catFilter.id}: true | filter:productSearch | filter:product.name | orderBy: 'name'">
    <p ng-bind="product.name.language"></p>
    <table ng-repeat="cat in product.associations.categories">
        <tr ng-repeat="attr in cat.@attributes">
            <td >{{attr.nodeType}}</td>
            <td >{{attr.api}}</td>
        </tr>
    </table>
</div>

Have a look here: https://www.aspsnippets.com/Articles/AngularJS-Using-ng-repeat-with-Complex-Nested-JSON-objects.aspx

like image 80
Harry Avatar answered Sep 19 '22 18:09

Harry


I think your only issue is accessing the @attributes with the dot notation like so product.associations.categories.@attributes

this is not valid javascript, so instead you should use the bracket notation for this attributes.

like so: product.associations.categories['@attributes']

like image 34
Tiago Coelho Avatar answered Sep 21 '22 18:09

Tiago Coelho