Can't access variables from json

I want to filter a json(get) from my supplier and export(post) to my Shop to update some fields of the products i have online. The problem is i can’t figure how to access the values i need. The values i need are:

id,
availability,
amount,
prot_lianiki

Example of 1 product contained in the JSON i need to filter:

{"products": {
    "6416": {
        "id": "",
        "title": "",
        "image": "",
        "video": ,
        "images": {
            "51409": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51410": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51411": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51412": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51414": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            }
        },
        "sku": "",
        "amount": "",
        "weight": "",
        "length": "",
        "width": "",
        "height": "",
        "update": "",
        "prot_lianiki": ,
        "price": ,
        "discount": "",
        "list_price": "",
        "promo_text": "",
        "full_descr": "",
        "availability": "",
        "category_id": 2041,
        "category_path": "",
        "category_id_path": "",
        "fixed_price": "",
        "features": {
            "162": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "1117": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "27": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            }
        }
    }
}

My Code for loading the json to an array is:

pm.test(“array of all properties”, () => {
let jsonData = pm.response.json()
arrayOfObject = jsonData;

const obj = Object.assign({}, arrayOfObject);

console.log(obj);

});

Can you please use the preformatted text option when posting JSON or code.

It’s nearly unreadable when its all aligned to the left.

pm.response.json() is parsing the response into a JavaScript object.

You should be able to access the elements directly.

Although you have all of your product codes under numbers, not names.

Are you trying to create an array of all of the products, but just including the four fields you mentioned?

const json = 

{"products": {
    "6416": {
        "id": "Test ID",
        "title": "",
        "image": "",
        "video": "",
        "images": {
            "51409": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51410": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51411": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51412": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51414": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            }
        },
        "sku": "",
        "amount": "£100",
        "weight": "",
        "length": "",
        "width": "",
        "height": "",
        "update": "",
        "prot_lianiki": "Test prot_lianiki",
        "price": "",
        "discount": "",
        "list_price": "",
        "promo_text": "",
        "full_descr": "",
        "availability": "Test Availability",
        "category_id": 2041,
        "category_path": "",
        "category_id_path": "",
        "fixed_price": "",
        "features": {
            "162": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "1117": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "27": {
                "feature_name": "", 
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            }
        }
    }
}}

console.log(json);

pm.test('json is an object', () => {
    pm.expect(json).to.be.an('object');
});

console.log(json.products["6416"].id);
console.log(json.products["6416"].availability);
console.log(json.products["6416"].amount);
console.log(json.products["6416"].prot_lianiki);

This is something else you can try.

As I don’t have direct access to your response, I’ve created a variable to store your sample and added test data to the elements that you are interested in.

const jsonData = 

{"products": {
    "6416": {
        "id": "Test ID",
        "title": "",
        "image": "",
        "video": "",
        "images": {
            "51409": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51410": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51411": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51412": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            },
            "51414": {
                "pair_id": "",
                "image_id": "",
                "detailed_id": "",
                "position": "",
                "detailed": {
                    "image_path": "",
                    "alt": "",
                    "image_x": "",
                    "image_y": "",
                    "http_image_path": "",
                    "https_image_path": "",
                    "absolute_path": "",
                    "relative_path": ""
                }
            }
        },
        "sku": "",
        "amount": "£100",
        "weight": "",
        "length": "",
        "width": "",
        "height": "",
        "update": "",
        "prot_lianiki": "Test prot_lianiki",
        "price": "",
        "discount": "",
        "list_price": "",
        "promo_text": "",
        "full_descr": "",
        "availability": "Test Availability",
        "category_id": 2041,
        "category_path": "",
        "category_id_path": "",
        "fixed_price": "",
        "features": {
            "162": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "1117": {
                "feature_name": "",
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            },
            "27": {
                "feature_name": "", 
                "feature_value_sel": "",
                "feature_id": "",
                "variant_id": ""
            }
        }
    }
}}

The following function is not mine but will help when trying to search.

//return an array of objects according to key, value, or key and value matching
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(obj);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(obj);
            }
        }
    }
    return objects;
}

All credit for that function goes to the original poster.

http://techslides.com/how-to-parse-and-search-json-in-javascript

Let’s have a look at the data we are working with.

// const jsonData = pm.response.json()
console.log(jsonData); // This has already been parsed into a JavaScript object

This returns the following which should match your json example.

Using the function previously provided, you can search for an element. As all of the elements you want are under the same leaf. I’ve just searched for the id that matches the test data I put in.

//example of grabbing objects that match some key and value in JSON

var search = (getObjects(jsonData,'id','Test ID'));

console.log(search);

//returns 1 object where a key names 'id' has the value 'Test ID'

This has one result which you can target directly like in the following example;

console.log(search[0].id);
console.log(search[0].amount);
console.log(search[0].prot_lianiki);
console.log(search[0].availability);

image

Or we could if we want map just the fields you are interested in and create a new array to work with.

var mappedResults = search.map(({ id, amount, prot_lianiki, availability }) => ({ id, amount, prot_lianiki, availability }));
console.log(mappedResults);

image

Hope this gives you some ideas on how to target those elements.

Although you have all of your product codes under numbers, not names.

Unfortunately thats the stacture that i get from the supplier…

Are you trying to create an array of all of the products, but just including the four fields you mentioned?

Yeah thats exactly what i want to achieve, and then store it in a global variable and post it to my online store.

if it helps the json link for ex 3 products is: Link

I can’t see how this would work.

Are you expecting to have more than one product code or is it just a single product code in each response?

If its more than one product, then you would need to include the product code in the array to separate the elements.

I’m not quite understanding how you then want to store this in a variable. As an array, a string, or JSON. A single variable, or individual ones for each element?

The normal usage would be for each element to be assigned to an individual variable to be used in the next post request. (Not an array of all of the products).

This really is determined by what the API for the Post request will accept.

If it really is an array, then I suspect you will need to create a loop to go through each element in the array, and use sendRequest to post.

Have a look at the following.

Using the same method and function as detailed in the previous request.


const jsonData = {......}

//return an array of objects according to key, value, or key and value matching
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(obj);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(obj);
            }
        }
    }
    return objects;
}

var mappedResults = (getObjects(jsonData,'id','')).map(({ id, amount, prot_lianiki, availability }) => ({ id, amount, prot_lianiki, availability }));
console.log(mappedResults);

image

// turn this back into a JSON string

var json = JSON.stringify(mappedResults);
console.log(json);

Have no idea if this is really what you need. You need to detail what the API will accept for the follow on post request.

As for storing variables, please take a look at the following.

Currently i have made a collection and inside i have made multiple get requests to store the values i need.

The code that each GET request has is the following with the first “GET” request setting the collection variable productsUpdate empty.

responseJson = pm.response.json();

pm.collectionVariables.set("productsUpdate", );
//console.log(pm.collectionVariables.get("productsUpdate"));

//return an array of objects according to key, value, or key and value matching
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(obj);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(obj);
            }
        }
    }
    return objects;
}
var mappedResults = (getObjects(responseJson,'id','')).map(({ id, amount, prot_lianiki, availability }) => ({ id, amount, prot_lianiki, availability }));
//console.log(mappedResults);
pm.collectionVariables.set("productsUpdate", mappedResults);
//console.log(pm.collectionVariables.get("productsUpdate"));


//console.log(responseJson.products["6416"].id);
//console.log(responseJson.products["6416"].availability);
//console.log(responseJson.products["6416"].amount);
//console.log(responseJson.products["6416"].prot_lianiki);

Then i need to post the data stored in the collection variable thus the “POST” request which has the following code.

// in the pre-request script
var body = pm.collectionVariables.get('productsUpdate')
pm.collectionVariables.set('req_body', JSON.stringify(body));
// in the body
{{req_body}}

The thing is that in my aplication i have specific limitations on how to import data(see picture below), and i can’t find how to do that or even if it is possible.

I can’t see how having all of your requests in one folder will work.

Your variable will only have the results of the last GET request before the POST request is sent.

It looks like you should have each GET request in its own sub-folder, with an corresponding POST request.

However, looking at the screenshot on the import methods, then I can’t see how this will be of any benefit.

The import tool can use “File from URL”, but this means you need to have the file uploaded to a webserver first. The import tool is going to pull from that location. (Potentially using a GET request). It doesn’t look like you can POST to the import tool. You will have to post to a local server (one that you control) and then set the import to pick up the file from this location.

Have you considered just sticking the updates in a CSV file, and then using the file upload option instead?