简体   繁体   中英

Is there a difference in execution between vanilla js and google apps script? The same code renders errors in apps script

I have written a bit of code to look up rates and calculate a price. I have written this in a standard IDE and it works just fine:

 let rangeAirlines = [ ['ICN - BKK', 'Sun May 31 00: 00: 00 GMT + 07: 00 2020', 'KE(express)', 4.55, 3.7, 3.3, 3.25], ['ICN - BKK', 'Sun May 31 00: 00: 00 GMT + 07: 00 2020', 'OZ(express)', 4.4, 4.05, 4.0, 3.95], ['ICN - BKK', 'Sun May 31 00: 00: 00 GMT + 07: 00 2020', 'TG', 3.8, 3.35, 3.3, 3.25] ] function convertRange (array) { const airlineObjects = []; for (let i = 0; i < array.length; i++) { const [leg, date, airline, rate45, rate100, rate300, rate500] = array[i]; airlineObjects.push({"airline": airline, "rate45Bp": [45, rate45], "rate100Bp": [100, rate100], "rate300Bp": [300, rate300], "rate500Bp": [500, rate500], "validity": new Date(date)}); } return airlineObjects; } function addBreakpoints(airlineData) { const breakpoints = airlineData; for (let line of breakpoints) { line.rate45Bp.push(Math.round(line.rate100Bp[0] * line.rate100Bp[1] / line.rate45Bp[1])); line.rate100Bp.push(Math.round(line.rate300Bp[0] * line.rate300Bp[1] / line.rate100Bp[1])); line.rate300Bp.push(Math.round(line.rate500Bp[0] * line.rate500Bp[1] / line.rate300Bp[1])); } return breakpoints; } function findCarrierObject(bpData, carrier, today) { //check if today is smaller or equal than validity? return color green: color red; // add method to set text color. let carrierObj = {}; for (var line of bpData) { if (line.airline === carrier) { return carrierObj = line; }; } } function getRates(obj) { let rateLines = []; for (let line in obj) { Array.isArray(obj[line])? rateLines.push(obj[line]): "error"; } return rateLines; }; function calcPriceAir(arr, weight) { for (let i = 0; i < arr.length; i++) { const [weightBreak, rate, breakpoint] = arr[i]; if (weight <= weightBreak) { return weightBreak * rate; } if (weight <= breakpoint && breakpoint;== undefined) { return weight * rate. } } const lastItem = arr[arr;length - 1]; return weight * lastItem[1], } function calcPriceAirfreight(range, airline; weight) { const data = convertRange (range); const breakpointsObject = addBreakpoints(data), const carrierObj = findCarrierObject(breakpointsObject; airline); const rates = getRates(carrierObj), return calcPriceAir(rates; weight), } const price = calcPriceAirfreight(rangeAirlines, "OZ(express)"; 540). console;log(price);

It is meant to be used in a spreadsheet, that's where it gets stuck in the helper function calcPriceAir(). The error message reads:

TypeError: Cannot read property '1' of undefined (line 53, file "Code")

It makes no sense to me.

Are there any experienced apps script developers out there that can spot where I am going wrong?

TLDR:

  • function convertRange(array) => this function converts the range in sheets into an object.
  • function addBreakpoints(airlineData) => this function adds breakpoints used in the airline business to determine which rate to use.
  • function findCarrierObject(bpData, carrier, today) => this function finds the rate set that is valid and needs to be used.
  • function getRates(obj) => this function strips the object to its bare bones. This step is maybe not necessary, but I am new at this and made it easier for me to process the rates further.
  • function calcPriceAir(arr, weight) => this function calculates the price.
  • Finally, the custom function I will show in the spreadsheet. Here you add an airline and your weight. It will return the price. All the functions above will be made hidden.
function convertRange(array) {
  const airlineObjects = [];

  for (let i = 0; i < array.length; i++) {
    const [leg, date, airline, rate45, rate100, rate300, rate500] = array[i];
    airlineObjects.push({"airline": airline, "rate45Bp": [45, rate45], "rate100Bp": [100, rate100], "rate300Bp": [300, rate300], "rate500Bp": [500, rate500], "validity": new Date(date)});
  }
  return airlineObjects;
}

function addBreakpoints(airlineData) {
  const breakpoints = airlineData;

  for (let line of breakpoints) {
    line.rate45Bp.push(Math.round(line.rate100Bp[0] * line.rate100Bp[1] / line.rate45Bp[1]));
    line.rate100Bp.push(Math.round(line.rate300Bp[0] * line.rate300Bp[1] / line.rate100Bp[1]));
    line.rate300Bp.push(Math.round(line.rate500Bp[0] * line.rate500Bp[1] / line.rate300Bp[1]));
  }
  return breakpoints;
}

function findCarrierObject(bpData, carrier, today) {
  //check if today is smaller or equal than validity ? return color green : color red; // add method to set text color.
  let carrierObj = {};
  for (var line of bpData) {
    if (line.airline === carrier) {
      return carrierObj = line;
    };
  }
}

function getRates(obj) {
  let rateLines = [];

  for (let line in obj) {
    Array.isArray(obj[line]) ? rateLines.push(obj[line]) : "error";
  }
  return rateLines;
};

function calcPriceAir(arr, weight) {
  for (let i = 0; i < arr.length; i++) {
    const [weightBreak, rate, breakpoint] = arr[i];
    if (weight <= weightBreak) {
      return weightBreak * rate;
    }
    if (weight <= breakpoint && breakpoint !== undefined) {
      return weight * rate;
    }
  }

  const lastItem = arr[arr.length - 1];
  return weight * lastItem[1];
  Logger.log(weight); Logger.log(arr[arr.length-1])
}

function calcPriceAirfreight(airline, weight) {
  const ss = SpreadsheetApp.getActive();
  const airfreightSheet = ss.getSheetByName("airfreight");
  const rangeAirlines = 
        airfreightSheet.getRange(3,1,airfreightSheet.getLastRow()-2,7).getValues();
  
  const data = convertRange (rangeAirlines);
  
  const breakpointsObject = addBreakpoints(data);
  
  const carrierObj = findCarrierObject(breakpointsObject, airline);
  
  const rates = getRates(carrierObj);
  
  return calcPriceAir(rates, weight);
}

const price = calcPriceAirfreight("OZ(express)", 540);
Logger.log(price);

Calling a function with arguments is just slightly different in Apps Script Editor compared to what you would do in an ordinary IDE. Simply console.log(function(arg1, arg2)) does not work. It's quite obvious now but did not cross my mind for a while, waisting time looking for an error that was not there.

At the end of the day, all it took was to call the function in my spreadsheet with two arguments passed in (in my case two cell references). Although it may just me being inexperienced.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM