SheetJS Change Header names to dynamic - sheetjs

I am trying to change the header names in sheetJS to something I recieve from the form. Here is my form submit function:
onFormSubmit() {
const fileReader = new FileReader();
const solution = 'testsolution'; // normally i get this from a form input
fileReader.onload = (e) => {
this.arrayBuffer = fileReader.result;
const data = new Uint8Array(this.arrayBuffer);
const arr = [];
for (let i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
const bstr = arr.join('');
const workbook = XLSX.read(bstr, {type: 'binary'});
const first_sheet_name = workbook.SheetNames[0];
const worksheet = workbook.Sheets[first_sheet_name];
// change the column names to match entity
const records = XLSX.utils.sheet_to_json(worksheet, {raw: true});
console.log('records - ', records);
};
fileReader.readAsArrayBuffer(this.file);
}
currently for example my headers come in like this:
AltId, FirstName, LastName
And I want them to end up like this with 'testsolution' apended with underscore and lowercase
testsolution_altid, testsolution_firstname, testsolution_lastname
NOTE: Header names may change depending on what sheet is uploaded. For example the next sheet uploaded may contain headers:
AltId, Address1, Address2, City, State
And should end up like
testsolution_altid, testsolution_address1, testsolution_address2, testsolution_city, testsolution_state
Any help would be appriciated!

I ended up doing it like this if it helps anyone else:
// change the column names to match entity
const newHeaders = [];
const columnCount = XLSX.utils.decode_range(ws['!ref']).e.c +1;
console.log(columnCount);
for (let i = 0; i < columnCount; ++i) {
newHeaders[i] = solution+'_'+ ws[`${XLSX.utils.encode_col(i)}1`].v.toLowerCase();
// console.log(header[i]);
}
// console.log(newHeaders);

Related

ethers.js, Swap on uniswapV3 failed tx

Im trying to use exactInput() function for UniV3 interface but when trying to execute the code the transactions fails https://goerli.etherscan.io/tx/0xb0d5e4b491610b9db8d98cc938008ba2a4e1a06e67b05ed87ac6c0ca3ad61dab
I know eth send shows 0 in this one but even especifying amount it fails, I dont know what to change..
I have checked many codes out there and cant see the mistake, please could someone give me some advice?
const {abi: V3SwapRouterABI} = require('#uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
const { ethers } = require("ethers")
require("dotenv").config()
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET
const PRIVATE_KEY = process.env.PRIVATE_KEY
const WALLET_ADDRESS = process.env.WALLET_ADDRESS
// now you can call sendTransaction
const wethToken= "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
const Uni= "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const UniswapRouter="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
const UniV3Contract = new ethers.Contract(
UniswapRouter,
V3SwapRouterABI
)
const provider = new ethers.providers.JsonRpcProvider(INFURA_URL_TESTNET)
const wallet = new ethers.Wallet(PRIVATE_KEY)
const signer = wallet.connect(provider)
const FEE_SIZE = 3
function encodePath(path, fees) {
if (path.length != fees.length + 1) {
throw new Error('path/fee lengths do not match')
}
let encoded = '0x'
for (let i = 0; i < fees.length; i++) {
// 20 byte encoding of the address
encoded += path[i].slice(2)
// 3 byte encoding of the fee
encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
}
// encode the final token
encoded += path[path.length - 1].slice(2)
return encoded.toLowerCase()
}
async function getToken() {
const path = encodePath([wethToken, Uni], [3000])
const deadline = Math.floor(Date.now()/1000) + (60*10)
const params = {
path: path,
recipient: WALLET_ADDRESS,
deadline: deadline,
amountIn: ethers.utils.parseEther('0.01'),
amountOutMinimum: 0
}
const encodedData = UniV3Contract.interface.encodeFunctionData("exactInput", [params])
const txArg = {
to: UniswapRouter,
from: WALLET_ADDRESS,
data: encodedData,
gasLimit: ethers.utils.hexlify(1000000)
}
const tx = await signer.sendTransaction(txArg)
console.log('tx: ', tx)
const receipt = tx.wait()
console.log('receipt: ', receipt)
}
module.exports = { getToken
You will need to remove the Deadline.. The new router 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 moved deadline to the multi-call function (since the router is designed to be multi-call)

How to remove time component from date fields while exporting to excel using sheetjs

I am able to export a list of JSON objects to an excel file using sheetjs in angular. One of the requirements is, user should be able to sort and filter the date fields like below.
But as you can see, along with the date part, the time part also comes while filtering. Is there a way, I can remove the time part and still be able to do the filtering like above?
Here is my code.
exportToExcel(arrData: any[], fileName: string, formattingData: ExcelFormattingData = undefined) {
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(arrData, {cellDates: true, dateNF: this.userAuthToken.dateFormat});
if(formattingData != null) {
const range = XLSX.utils.decode_range(worksheet['!ref']);
for (let j = range.s.c; j <= range.e.c; j++) {
let ref_columnHeader = XLSX.utils.encode_cell({r:range.s.r, c:j});
let columnName = worksheet[ref_columnHeader].v;
if(formattingData.Values.includes(columnName)){
for(let i = range.s.r + 1; i <= range.e.r; ++i) {
let ref = XLSX.utils.encode_cell({r:i, c:j});
if(worksheet[ref] != null) {
worksheet[ref].t = 'd';
worksheet[ref].z = formattingData.Format;
}
}
}
}
}
const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' });
FileSaver.saveAs(blob, fileName);
}

for loop only iterating twice with axios

const [Datalist,setDatalist] = useState([]);
useEffect(() => {
axios.get( 'http://0.0.0.0:8000/api/v1/questions/history/1')
.then(response => {
const questions = response.data;
const datalist = [];
for (let i = 0; i < questions.length - 1; i++) {
const data = new Object();
data.isExpanded = false;
data.question_id = questions[i].id;
data.question = questions[i].content;
data.type = questions[i].type;
data.commentType = questions[i].comment_type;
data.answer = [];
datalist.push(data);
}
setDatalist(datalist);
});
},[]);
I have three questions in my database currently. The for loop should be iterating through 0 to 2, however, it is only iterating twice.
And I'm also having problems putting the data into Datalist.
Anybody know where the issue is??
Thanks in advance!!
Change your for loop to this:
for (let i = 0; i < questions.length; i++)
Since you are iterating over each question you receive, you could use the map-method (if your environment supports ES6-Syntax - but since you're using react, it most likely dooes).
From the MDN Docs:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
With map, your code could look like this:
(Also note the removal of const data = new Object();. you can initialize an object and assign its properties/values at the same time)
const [Datalist,setDatalist] = useState([]);
useEffect(() => {
axios.get( 'http://0.0.0.0:8000/api/v1/questions/history/1')
.then(response => {
const questions = response.data;
const datalist = questions.map(question => {
return {
isExpanded: false;
question_id: question.id;
question: question.content;
type: question.type;
commentType: question.comment_type;
answer: [];
};
});
setDatalist(datalist);
});
},[]);

How to connect Dear inventory APIs and Google sheet?

I would like to connect the Dear inventory system with Google Sheets for importing product lists, Sale lists data, etc by using both the Dear API and Google Sheets API.
It should be automatically updated.
Is it possible or not?
If yes, Any methods here?
Sure this is possible. With this you have a generic setup that will NOT handle nested objects or arrays. But you can create specific functions with the data you want. But for that you should hire somebody, or do the work yourself.
The setup is that you can use the generic function to get the endpoint you want to the sheet you want. dearAPI(endpoint, sheetname, dig)
Dig: This is the object that holds the array of the returned data:
The code:
//GLOBAL variables:
const accountID = 'id';
const secret = 'secret';
function onOpen(e) {
SpreadsheetApp.getUi().createMenu('DEAR')
.addItem('Update all', 'updateAll')
.addToUi();
}
function updateAll(){
dearAPI('product','Products','Products');
dearAPI('salesList','Sales', 'SalesList');
}
/**
* Updates data from specific DEAR endpoint to specific sheet.
*
* #param {string} endpoint - the endpoint the get the data from.
* #param {string} sheetname - name of the sheet to write the data to.
* #param {string} dig - the object where the array of data is returned.
* #return {void}
*/
function dearAPI(endpoint, sheetname, dig) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetname)
const dataRows = [];
let pagenumber = 1;
do {
const url = `https://inventory.dearsystems.com/externalapi/v2/${endpoint}?page=${pagenumber}&limit=1000`;
const headers = {
"api-auth-accountid": accountID,
"api-auth-applicationkey": secret
};
const options = {
"method" : "get",
"headers" : headers
};
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText())
data[dig].forEach(item => dataRows.push(item));
pagenumber++
} while (data.Total != data.Page)
const rowHeaders = Object.keys(dataRows[0]);
const rows = [rowHeaders];
for (let i = 0; i < dataRows.length; i++) {
const rowData = [];
for (let j = 0; j < rowHeaders.length; j++) {
rowData.push(dataRows[i][rowHeaders[j]]);
}
rows.push(rowData);
}
sheet.getRange(1,1,sheet.getLastRow(), sheet.getLastColumn()).clearContent();
sheet.getRange(1,1,rows.length,rows[0].length).setValues(rows);
}

How to send the index of a for loop into the promise of a function in a Vue Resource call?

I am looping through an object however in the asynchronous part the i variable is always five.
How can I maintain that value, or pass it into the function
getProductData: function() {
var vm = this;
for (var i = 0; i < vm.recommendationResponse['recommendedItems'].length; i++) {
var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
// get body data
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
}, response => {
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
});
}
}
I I do something like this:
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then((response, i) => ...
then i is undefined
Who do I keep the index of the loop or should I go about it a different way?
Always use let to initialize variables in for loop when dealing with async operations. Similar things goes to having for loops in intervals. By using let you make sure you always have a unique variable assigned to i.
for (let i = 0, recommendationlength = vm.recommendationResponse['recommendedItems'].length; i < recommendationlength; i++)
Little bonus, if you cache array length in the beginning you get a small performance boost :-)
You could use Array.prototype.forEach instead:
var vm = this;
vm.recommendataionResponse['recommendedItems'].forEach((item, i) => {
var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
// get body data
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
}, response => {
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
});
})
This way, since there is a unique scope for each i value, each .then callback will be able to reference the correct value.