ParamQuery Grid (pqgrid) updateRow with dynamic values for keys - object

I have a huge problem with ParamQuery. I'm using the updateRow method for update a row below the documentation:
$( ".selector" ).pqGrid( "updateRow",
{ rowIndx: 2, row: { 'ProductName': 'Cheese', 'UnitPrice': 30 } );
However I need that 'ProductName', 'UnitPrice', etc.. etc... will be programmatically read from an array of values. How can I do it?
For example if my array at position 2 contains ProductName it's not possible to do
$( ".selector" ).pqGrid( "updateRow",
{ rowIndx: 2, row: { **myArray[2]**: 'Cheese', 'UnitPrice': 30 } );
Any ideas?
thanks in advance.
Solution
var obj = {};
for(var i = 0; i < myarray.length; i++) {
var key = myarray[i];
var val = '44';
obj[key] = val;
}
$( ".selector" ).pqGrid( "updateRow",
rowIndx: 2,
row: obj
});
thanks anyway :)

Related

Correct way to work with multiple repeating loops for sum of values

I'm working on a function that aims to return a non-repeating list of years for all transactions.
So far it worked fine, but I also need to add up all the values of the transactions for each year that it returned in the first loop.
I tried different ways and without success.
public async getListYear(): Promise<any>{
try{
return await client
.scan({
TableName: 'dbPayments'
})
.promise()
.then((response) => {
let result = response.Items.filter((e, i) => {
return response.Items.findIndex((x) => {
return x.date_created.substring(0,4) == e.date_created.substring(0,4)
}) == i;
});
let years = [];
let sum = [];
for(let i = 0; i < result.length; i++){
const yearTransaction = new Date(response.Items[i]['date_created']).getFullYear();
years.push(yearTransaction)
}
// Here is the problem, I tried as follows:
for(let i = 0; i < response.Items.length; i++){
if(response.Items[i]['status_pgm'] == 'approved'){
for(let i = 0; i < years.length; i++){
let year = new Date(response.Items[i]['date_created']).getFullYear();
let value = 0;
if(year == years[i]){
value += response.Items[i]['transaction_amount']
}
let data = {
years[i]: value
}
sum.push(data)
}
}
}
return {
status: 200,
list: years,
totalSum: sum
}
})
.catch((error: AxiosError) => {
throw error;
})
}catch (e) {
console.log(e);
return {status: 500, msg: "error"}
}
}
Table dbPayments:
id | date_created | transaction_amount | status_pgm
1 2022-10-29T20:54:40.294-04:00 45 approved
2 2022-09-29T20:54:40.294-04:00 30 approved
3 2022-08-29T20:54:40.294-04:00 25 approved
4 2021-10-29T20:54:40.294-04:00 15 approved
5 2021-09-29T20:54:40.294-04:00 10 approved
I need to return the sum of values for each year, what is the best way to do this? In the code I put an example of how I tried to do it.
First. I think this is the kind of operation should be done on the DB not in client.
But i notice some errors.
for(let i = 0; i < response.Items.length; i++){
if(response.Items[i]['status_pgm'] == 'approved'){
for(let i = 0; i < years.length; i++){
Inner and outer loop both use i so this mught clash and mess up the looping.
let year = new Date(response.Items[i]['date_created']).getFullYear();
I think this should be on outer loop not inner loop.
let value = 0;
if(year == years[i]){
value += response.Items[i]['transaction_amount']
}
let data = {
years[i]: value
}
value is set to 0 each time this piece of code is reaches, so no accumulation is actually made.
My reccomendation. Make a Map<number, number>, where key is year and value is the accumulated sum. Then you just could
for(let i = 0; i < response.Items.length; i++){
if(response.Items[i]['status_pgm'] == 'approved'){
let year = new Date(response.Items[i]['date_created']).getFullYear();
let value = response.Items[i]['transaction_amount'];
map.set(year, map.get(year) + value || value)
}
}
And if you need it as a array of sums like in the example, you could then create the array by iterating over years array, and then pushing the corresbonding years sum into a sums array.
for(let i = 0; i < years.length; i++){
let year = years[i];
let obj= {};
obj[year] = map.get(year);
sums.push(obj);
}

Google Sheet custom function not returning string

I am new to Google Sheet scripting.
I am writing a code to strip the sixth components from a long text that is based on a naming convention. The text have 6 parts all separated by an underscore. However, my code is not returning anything
function RetailerStrip(account) {
var count = 0;
var retname = "";
var retcount = 0;
for(var i = 0, len = account.length; i < len; i++) {
if (account[i] =="_") {
++count;
}
if (count == 5) {
retname[retcount]= account[i];
++retcount;
}
}
return retname;
}
I then call this function from sheet as below
=RetailerStrip("abc_def_ghi_jkl_mno_pqr")
When I tried to declare 'retname' as an array the function did return the required text (fifth component) but the text was spread across multiple cells with on character in each cell, and not as a single string in one cell
var retname = [];
Please help
You could try this:
function RetailerStrip(str) { return str.split('_')[5]; }
The split() method creates an array.
But if you prefer to stick with the string-iteration method, you could use this:
function RetailerStrip(account) {
var count = 0;
var retname = []; // Array
var retcount = 0;
for (var i = 0, len = account.length; i < len; i++) {
if (account[i] =="_") {
++count;
}
if (count == 4) {
retname[retcount]= account[i];
++retcount;
}
}
retname.shift(); // To get rid of the underscore from the array
var retnameString = retname.join(''); // To convert the array to a string
return retnameString;
}

How to get over 1000 records from a SuiteScript Saved Search?

Below is code I came up with to run a Saved Search in NetSuite using SuiteScript, create a CSV with the Saved Search results and then email the CSV. The trouble is, the results are limited to 1000 records. I've researched this issue and it appears the solution is to run a loop that slices in increments of 1000. A sample of what I believe is used to slice searches is also below.
However, I cannot seem to be able to incorporate the slicing into my code. Can anyone help me combine the slicing code with my original search code?
var search = nlapiSearchRecord('item', 'customsearch219729');
// Creating some array's that will be populated from the saved search results
var content = new Array();
var cells = new Array();
var temp = new Array();
var x = 0;
// Looping through the search Results
for (var i = 0; i < search.length; i++) {
var resultSet = search[i];
// Returns an array of column internal Ids
var columns = resultSet.getAllColumns();
// Looping through each column and assign it to the temp array
for (var y = 0; y <= columns.length; y++) {
temp[y] = resultSet.getValue(columns[y]);
}
// Taking the content of the temp array and assigning it to the Content Array.
content[x] += temp;
// Incrementing the index of the content array
x++;
}
//Inserting headers
content.splice(0, 0, "sku,qty,");
// Creating a string variable that will be used as the CSV Content
var contents;
// Looping through the content array and assigning it to the contents string variable.
for (var z = 0; z < content.length; z++) {
contents += content[z].replace('undefined', '') + '\n';
}
// Creating a csv file and passing the contents string variable.
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', contents.replace('undefined', ''));
// Emailing the script.
function SendSSEmail()
{
nlapiSendEmail(768, 5, 'Inventory Update', 'Sending saved search via scheduled script', 'cc#email.com', null, null, file, true, null, 'cc#email.com');
}
The following code is an example of what I found that is used to return more than a 1000 records. Again, as a novice, I can't seem to incorporate the slicing into my original, functioning SuiteScript. Any help is of course greatly appreciated.
var filters = [...];
var columns = [...];
var results = [];
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
var resultset = savedsearch.runSearch();
var searchid = 0;
do {
var resultslice = resultset.getResults( searchid, searchid+1000 );
for (var rs in resultslice) {
results.push( resultslice[rs] );
searchid++;
}
} while (resultslice.length >= 1000);
return results;
Try out this one :
function returnCSVFile(){
function escapeCSV(val){
if(!val) return '';
if(!(/[",\s]/).test(val)) return val;
val = val.replace(/"/g, '""');
return '"'+ val + '"';
}
function makeHeader(firstLine){
var cols = firstLine.getAllColumns();
var hdr = [];
cols.forEach(function(c){
var lbl = c.getLabel(); // column must have a custom label to be included.
if(lbl){
hdr.push(escapeCSV(lbl));
}
});
return hdr.join(",");
}
function makeLine(srchRow){
var cols = srchRow.getAllColumns();
var line = [];
cols.forEach(function(c){
if(c.getLabel()){
line.push(escapeCSV(srchRow.getText(c) || srchRow.getValue(c)));
}
});
return line.join(",");
}
function getDLFileName(prefix){
function pad(v){ if(v >= 10) return v; return "0"+v;}
var now = new Date();
return prefix + '-'+ now.getFullYear() + pad(now.getMonth()+1)+ pad(now.getDate()) + pad( now.getHours()) +pad(now.getMinutes()) + ".csv";
}
var srchRows = getItems('item', 'customsearch219729'); //function that returns your saved search results
if(!srchRows) throw nlapiCreateError("SRCH_RESULT", "No results from search");
var fileLines = [makeHeader(srchRows[0])];
srchRows.forEach(function(soLine){
fileLines.push(makeLine(soLine));
});
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', fileLines.join('\r\n'));
nlapiSendEmail(768, 5, 'Test csv Mail','csv', null, null, null, file);
}
function getItems(recordType, searchId) {
var savedSearch = nlapiLoadSearch(recordType, searchId);
var resultset = savedSearch.runSearch();
var returnSearchResults = [];
var searchid = 0;
do {
var resultslice = resultset.getResults(searchid, searchid + 1000);
for ( var rs in resultslice) {
returnSearchResults.push(resultslice[rs]);
searchid++;
}
} while (resultslice.length >= 1000);
return returnSearchResults;
}
I looked into your code but it seems you're missing the label headers in the generated CSV file. If you are bound to use your existing code then just replace
var search = nlapiSearchRecord('item', 'customsearch219729');
with
var search = getItems('item', 'customsearch219729');
and just use the mentioned helper function to get rid off the 1000 result limit.
Cheers!
I appreciate it has been a while since this was posted and replied to but for others looking for a more generic response to the original question the following code should suffice:
var search = nlapiLoadSearch('record_type', 'savedsearch_id');
var searchresults = search.runSearch();
var resultIndex = 0;
var resultStep = 1000;
var resultSet;
do {
resultSet = searchresults.getResults(resultIndex, resultIndex + resultStep); // retrieves all possible results up to the 1000 max returned
resultIndex = resultIndex + resultStep; // increment the starting point for the next batch of records
for(var i = 0; !!resultSet && i < resultSet.length; i++){ // loop through the search results
// Your code goes here to work on a the current resultSet (upto 1000 records per pass)
}
} while (resultSet.length > 0)
Also worth mentioning, if your code is going to be updating fields / records / creating records you need to bear in mind script governance.
Moving your code to a scheduled script to process large volumes of records is more efficient and allows you to handle governance.
The following line:
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
can be adapted to your own saved search like this:
var savedsearch = nlapiLoadSearch('item', 'customsearch219729');
Hope this helps.

random-js array shuffle always returns the same result

I'm using NodeJS 0.12 with random-js to shuffle an array.
it seems that whenever I shuffle the array i get the same result, only when i restart the application the results differ.. only for the first time and then the same until i restart the application again.
this is my code:
var numbers = [1,2,3,4,5...];
var Random = require("random-js");
var random = new Random(Random.engines.mt19937().autoSeed());
function generateBalls() {
var result = random.shuffle(numbers);
return result;
}
any ideas?
More code:
this is the full ballsManagement.js file:
var maxNumber = 75;
var minNumber = 1;
var modNumber = 15;
var letters = ['B', 'I', 'N', 'G', 'O'];
var numbers = [];
var numbersToLetters = {};
var Random = require("random-js");
var random = new Random(Random.engines.mt19937().autoSeed());
for (var i = minNumber; i <= maxNumber; i++) {
numbersToLetters[i] = letters[i % modNumber];
}
for (var i = minNumber; i <= maxNumber; i++) {
numbers.push(i);
}
function generateBalls() {
var result = random.shuffle(numbers);
return result;
}
module.exports.generateBalls = generateBalls;
module.exports.maxNumber = maxNumber;
module.exports.minNumber = minNumber;
module.exports.modNumber = modNumber;
module.exports.letters = letters;
module.exports.numbers = numbers;
then i simply use the generateBalls function in the following code:
var ballsManagement = require('../models/ballsManagement');
var balls = ballsManagement.generateBalls();
var balls2 = ballsManagement.generateBalls();
...
thanks
You can use pure JS to shuffle any array, for example if you have an array such as
var arr = [0, 1, 2, 3, 4];
you can use this JS code:
var arr = [0, 1, 2, 3, 4];
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function getItemFromDB(){
var res = ["", "", "", "", ""];
for(var i=0; i<res.length; i++) {
var checker = false;
while(checker == false) {
var newItem = arr[getRandomInt(0, arr.length)];
if (res.indexOf(newItem) < 0) {
res[i] = newItem;
checker = true;
}
}
}
alert(res);
}
And this for HTML:
<form>
<input type='button' value='Get random array' onclick='getItemFromDB()'/>
</form>
It works for me just right.
it seems that the answer is pretty simple :)
the shuffle function modifies the array and returns it, it doesn't duplicate the array and modify the new array.
so in my case i used random twice so both balls and balls2 are pointing to the same array that has been shuffled twice.
so in my case i just create a new array before shuffling it.
function generateBalls() {
var newArr = [];
for (var i=minNumber;i<=maxNumber;i++) {
newArr.push(i);
}
Random.shuffle(engine,newArr);
return newArr;
}

Loop is not working in node.js

Here is my code :
for (var j in albums){
var album_images = albums[j].images
var l = album_images.length
for ( var i = 0; i < l; i++ ) {
var image = album_images[i]
Like.findOne({imageID : image._id, userIDs:user._id}, function(err,like){
if(like){
console.log(i)
//console.log(albums[j].images[i])
//albums[j].images[0].userLike = true;
}
})
}
}
Here I have albums, and I am populating images of album
So album variable contains all the albums and inside them their images will also be there in a array
I want to add a extra field (userLike) in each images.
Problem here is all the time the value of the i is 3 (that is the number of images in a album (album_images.length) - for the time being I have only one album)
I think the problem could be because the callback of Like.findOne calls only when all the loops has finished executing (just a guess).
How can I make it work so that I will get all the loop values in console.log(i) ?
Thanks in advance
I prefer using forEach:
albums.forEach(function(album, j) {
var album_images = album.images;
album_images.forEach(function(image, i) {
Like.findOne(...);
});
});
Just a tip: instead of performing a findOne for each image, you may consider using $in.
Alternatively you could define a function in order to have a scope where the variable doesn't change.
...
handle_album_image = function(image, i, j) {
Like.findOne({imageID : image._id, userIDs:user._id}, function(err, like){
if(like){
console.log(i)
//console.log(albums[j].images[i])
//albums[j].images[0].userLike = true;
}
})
}
for ( var i = 0; i < l; i++ ) {
var image = album_images[i]
handle_album_image(image, i, j)
}

Resources