1

I'm just learning javascript and I'm trying to update woocommerce products through GAS.

The issue in question is the following:

I have a variable that parses the response from woocommerce

for (let sku of skuSearch) {
    var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
    var url = surl
    Logger.log(url)

    var result = UrlFetchApp.fetch(url, optionsGet);
    if (result.getResponseCode() == 200) {

        var wooProducts = JSON.parse(result.getContentText());
        Logger.log(result.getContentText());

    }

Then I have another for to iterate and from a new array that contains id + sku of wooProducts and price from a different variable that takes the updated price from my sheet:

var idLength = wooProducts.length;
    Logger.log(idLength);
    for (var i = 0; i < idLength; i++) {
        var container = [];
        Logger.log(i);
        container.push({
            id: wooProducts[i]["id"],
            sku: wooProducts[i]["sku"],
            price: data[i]["price"],
        });

I can't tell exactly why it doesn't work. I mean the for loop works, it pushes id, sku and price in every loop, it's just that data[i] only provides the first ¿object? instead of looping like wooProducts which add +1 at every loop.

I'll copy 3 loops so it's crystal clear, I'm not sure it's already clear.

Loop 1:

[{"id":1622,"sku":"PD-1000-B","price":8145.9}]

Loop 2:

[{"id":1624,"sku":"PD-1007-A","price":8145.9}]

Loop 3:

[{"id":1625,"sku":"PD-1014","price":8145.9}]

As you can see id+sku change but price doesn't.

For further context, I'll include the data variable that is declaed outside the For:

const data = codigos.map(function(codigos, indice) {
    return {
        sku: codigos[0],
        price: precios[indice][0]
    }
})

//** EDIT:

I'm adding the entire code so it makes more sense maybe?

function getDataloopwoo() {
var ck = 'xxx'

var cs = 'xxx'

var website = 'xxx'

var optionsGet =

    {
        "method": "GET",
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "muteHttpExceptions": true,

    };    

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();
var skuSearch = sheet.getRange("A2:A").getValues();

const data = codigos.map(function(codigos, indice) {
    return {
        sku: codigos[0],
        price: precios[indice][0]
    }
})
Logger.log(skuSearch)

for (let sku of skuSearch) {
    var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
    var url = surl
    Logger.log(url)

    var result = UrlFetchApp.fetch(url, optionsGet);
    if (result.getResponseCode() == 200) {

        var wooProducts = JSON.parse(result.getContentText());
        Logger.log(result.getContentText());

    }
    var idLength = wooProducts.length;
    Logger.log(idLength);
    var container = [];
    for (var i = 0; i < idLength; i++) {            
        Logger.log(i);
        container.push({
            id: wooProducts[i]["id"],
            sku: wooProducts[i]["sku"],
            price: data[i]["price"],
        });
        
        Logger.log(container);
        var wooBatch = JSON.stringify(container);
        Logger.log(wooBatch);           
      }        
}

}

// FINAL EDIT with "solve":

So I figured it was inefficient to ask by 1 sku at a time, so now I'm asking by the 100, and paginating with a while if and saving id, sku, price to the container array. I will need now to compare the container array to the array with the updated prices and form a new array with id, sku and updated price, I'm reading up on that right now. The code:

function getDataloopwoo() {
var ck = 'xx'

var cs = 'xx'

var website = 'xx'

var optionsGet =

    {
        "method": "GET",
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "muteHttpExceptions": true,

    };    

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();    

const data = codigos.map(function(codigos, indice) {
    return {
        sku: codigos[0],
        price: precios[indice][0]
    }
})


var container = [];


    var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100";
    var url = surl
    //Logger.log(url)

    var result = UrlFetchApp.fetch(url, optionsGet);
    var headers = result.getAllHeaders();
    var total_pages = headers['x-wp-totalpages'];
    var pages_count = 0;
    while (pages_count < total_pages) {

    if (result.getResponseCode() == 200) {

        var wooProducts = JSON.parse(result.getContentText());
        //Logger.log(result.getContentText());
    }     
    
    
    for (var i = 0; i < wooProducts.length; i++) {            
        //Logger.log(i);
        container.push({
            id: wooProducts[i]["id"],
            sku: wooProducts[i]["sku"],
            price: wooProducts[i]["price"],
        });
        
        Logger.log(container);            
        
      }
      pages_count++;
      if (pages_count < total_pages){
        var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100" + "&page=" + (pages_count + 1);
        var url = surl
        var result = UrlFetchApp.fetch(url, optionsGet);
        Logger.log(url);
                    
      }        
}

}

vazcooo1
  • 181
  • 11
  • What does the variable `skuSearch` look like? Try logging it. Also, be weary of the difference between `for ... in` and `for ... of`. See [this](https://stackoverflow.com/questions/29285897/what-is-the-difference-between-for-in-and-for-of-statements). – code Dec 22 '21 at 18:37
  • skuSearch is a simple object that retrieves only SKU. log: [[PD-1000-B], [PD-1007-A], [PD-1014], [PD-1026]] – vazcooo1 Dec 22 '21 at 20:33
  • the for of works as inteded (I think), the idea is to loop the values of skuSearch so that it adds the sku to the url. – vazcooo1 Dec 22 '21 at 20:38

1 Answers1

2

You're reseting the array container in every iteration of the loop:

for (var i = 0; i < idLength; i++) {
    var container = []; // <-----------------here
    ...
    container.push({
    ...

I think the array should be defined outside the loop:

var container = [];
for (var i = 0; i < idLength; i++) {
    ...
    container.push({
    ...
Yuri Khristich
  • 13,448
  • 2
  • 8
  • 23
  • Thank you! I'll change that. I don't think it solves the issue with the data tho right? – vazcooo1 Dec 22 '21 at 20:32
  • Your sample code contains too many unknown variables. You need to make a reproducible piece of code — all variables should be defined inside the code. Actually, most of the errors disappear as soon as one tries to make a reproducible example. It's one of the most important skills in coding. – Yuri Khristich Dec 22 '21 at 21:25
  • Hi, I just added the entire code, to see if it would help. I posted also a sample spreadsheet and deleted the CK, CS variables from the WooCommerce API obviously, if it's important to check with a Woo API I can privde some temporary read keys to a staging site. – vazcooo1 Dec 23 '21 at 12:08
  • Thank you for the code. But there is two thing still: 1) I see no any return of the function `getDataloopwoo()`; 2) to make the code reproducible it would be enough to provide 2-3 sample of responses from the fetch method (`result = UrlFetchApp.fetch(url, optionsGet)`). You can log them and copy-paste here. You don't even need to provide any keys to WooCommerce API. For now I'm still sure that you need to move the definition of the array `container` outside the outer loop if you don't want to lost its contents. – Yuri Khristich Dec 23 '21 at 16:44
  • Thank you Yuri. I removed container from all loops but the iteration wasn't working and I started thinking it wasn't efficient at all to do what I was doing, so I decided to do pagination with a while if and push the results to the container. I'll edit what "solved" it. Although I still need to figure out how to compare two arrays and produce a third array with an updated price value. – vazcooo1 Dec 23 '21 at 17:58
  • Well. I'll be glad to help. – Yuri Khristich Dec 23 '21 at 19:17
  • But I don't get how your input and desired output should look like. Something like this: https://pastebin.com/e0SQ60kB ? – Yuri Khristich Dec 23 '21 at 19:38
  • Hello! Happy new year, I had covid like everyone in the universe right now, sorry I forgot about this thread! So I managed to do this: after the first array = wooProducts `let set = new Set(); for (let i = 0; i < data.length; i++) set.add(data[i]['sku']) for (let i = 0; i < container.length; i++) if (set.has(container[i]['sku'])) container[i]['price'] = data[i]['price']; Logger.log(container);` Which combines the two arrays into conteiner with the price from data. What I would like to do is actually compare values first. That JSON is good. – vazcooo1 Jan 04 '22 at 14:15
  • Which means I would like to compare wooProducts vs data and if the price from data is < than the price from wooProducts then create an update array that would contain, sku, id, updated price. I think pushing that to a new array I can manage (?) but I have no clue how to compare them. – vazcooo1 Jan 04 '22 at 14:20
  • 1
    Hi, congrats with the healing! The task doesn't sound like an extremely hard one. As far as I can tell. But it has become quite complicate because it's spread over several piece of code and over several comments. It would be better if you post it as a new question. Just show the samples of your two arrays (sets, objects) and the desired output and, I believe, you will get the solution in no time. Does it look like your input output? https://pastebin.com/e0SQ60kB – Yuri Khristich Jan 04 '22 at 21:55
  • 1
    Somewhat, it would actually be like this: https://pastebin.com/LLvE9mwj The new array would only have what is updated, if the price doens't change then it wouldn't appear in the new array. I can tell I used the wrong "<" what I meant was if the price in data was greater than that of wooProducts then it would go to a new array. I did ask it as a new question, I'll link you: https://stackoverflow.com/questions/70583634/comparing-one-value-from-two-arrays-if-bigger-then-copying-combining-into-thir – vazcooo1 Jan 05 '22 at 12:12