I am trying to read an excel document which has a datetime column.Uploading it to the website,instead of date column i get those numbers which represent the time.I know that using xlsx utils sheet to json we can convert the date cell to the format we want,but i am using a big function to parse this document and the only thing i use from xlsx is xlsx.read . in this function i wrote celldate to true but my web app throws the error that i can not use date object as react child and i dont understand how to convert it as string or at least to read objects property. Could you help me please?
excelToJson utility function which i use:
const XLSX = require("xlsx");
const extend = require("node.extend");
const excelToJson = (function () {
let _config = {};
const getCellRow = (cell) => Number(cell.replace(/[A-z]/gi, ""));
const getCellColumn = (cell) => cell.replace(/[0-9]/g, "").toUpperCase();
const getRangeBegin = (cell) => cell.match(/^[^:]*/)[0];
const getRangeEnd = (cell) => cell.match(/[^:]*$/)[0];
function getSheetCellValue(sheetCell) {
if (!sheetCell) {
return undefined;
}
if (sheetCell.t === "z" && _config.sheetStubs) {
return null;
}
return sheetCell.t === "n" || sheetCell.t === "d"
? sheetCell.v
: (sheetCell.w && sheetCell.w.trim && sheetCell.w.trim()) || sheetCell.w;
}
const parseSheet = (sheetData, workbook) => {
const sheetName =
sheetData.constructor === String ? sheetData : sheetData.name;
const sheet = workbook.Sheets[sheetName];
const columnToKey = sheetData.columnToKey || _config.columnToKey;
const range = sheetData.range || _config.range;
const headerRows =
(sheetData.header && sheetData.header.rows) ||
(_config.header && _config.header.rows);
const headerRowToKeys =
(sheetData.header && sheetData.header.rowToKeys) ||
(_config.header && _config.header.rowToKeys);
let strictRangeColumns;
let strictRangeRows;
if (range) {
strictRangeColumns = {
from: getCellColumn(getRangeBegin(range)),
to: getCellColumn(getRangeEnd(range)),
};
strictRangeRows = {
from: getCellRow(getRangeBegin(range)),
to: getCellRow(getRangeEnd(range)),
};
}
let rows = [];
for (let cell in sheet) {
// !ref is not a data to be retrieved || this cell doesn't have a value
if (
cell === "!ref" ||
(sheet[cell].v === undefined &&
!(_config.sheetStubs && sheet[cell].t === "z"))
) {
continue;
}
const row = getCellRow(cell);
const column = getCellColumn(cell);
// Is a Header row
if (headerRows && row <= headerRows) {
continue;
}
// This column is not _configured to be retrieved
if (columnToKey && !(columnToKey[column] || columnToKey["*"])) {
continue;
}
// This cell is out of the _configured range
if (
strictRangeColumns &&
strictRangeRows &&
(column < strictRangeColumns.from ||
column > strictRangeColumns.to ||
row < strictRangeRows.from ||
row > strictRangeRows.to)
) {
continue;
}
const rowData = (rows[row] = rows[row] || {});
let columnData =
columnToKey && (columnToKey[column] || columnToKey["*"])
? columnToKey[column] || columnToKey["*"]
: headerRowToKeys
? `{{${column}${headerRowToKeys}}}`
: column;
let dataVariables = columnData.match(/{{([^}}]+)}}/g);
if (dataVariables) {
dataVariables.forEach((dataVariable) => {
let dataVariableRef = dataVariable.replace(/[\{\}]*/gi, "");
let variableValue;
switch (dataVariableRef) {
case "columnHeader":
dataVariableRef = headerRows
? `${column}${headerRows}`
: `${column + 1}`;
// break;
default:
variableValue = getSheetCellValue(sheet[dataVariableRef]);
}
columnData = columnData.replace(dataVariable, variableValue);
});
}
if (columnData === "") {
continue;
}
rowData[columnData] = getSheetCellValue(sheet[cell]);
if (sheetData.appendData) {
extend(true, rowData, sheetData.appendData);
}
}
// removing first row i.e. 0th rows because first cell itself starts from A1
rows.shift();
// Cleaning empty if required
if (!_config.includeEmptyLines) {
rows = rows.filter((v) => v !== null && v !== undefined);
}
return rows;
};
const convertExcelToJson = function (config = {}) {
_config = config.constructor === String ? JSON.parse(config) : config;
// ignoring empty lines by default
_config.includeEmptyLines = _config.includeEmptyLines || false;
// source has to be defined and should have a value
if (!(_config.source)) {
throw new Error(":: 'source' required for _config :: ");
}
let workbook = XLSX.read(_config.source, {
type: "array",
});
let sheetsToGet =
_config.sheets && _config.sheets.constructor === Array
? _config.sheets
: Object.keys(workbook.Sheets).slice(
0,
(_config && _config.sheets && _config.sheets.numberOfSheetsToGet) ||
undefined
);
let parsedData = {};
sheetsToGet.forEach((sheet) => {
sheet =
sheet.constructor === String
? {
name: sheet,
}
: sheet;
parsedData[sheet.name] = parseSheet(sheet, workbook);
});
return parsedData;
};
return convertExcelToJson;
})();
export default excelToJson;
That is how i use it:
const convertExcelToObject = (file) => {
const reader = new FileReader();
reader.onload = function (event) {
const data = new Uint8Array(event.target.result);
let result = excelToJson({ source: data });
onUploadExcelFile(result.Transactions);
};
reader.readAsArrayBuffer(file);
};
And this is how i map it:
if (!excelData.length) {
return <div className="noFileContainer">No File Uploaded</div>;
}
const table = excelData;
const tableBody = table?.slice(1);
const tableHead = table[0];
const keys = Object.keys(tableHead);
tableBody.forEach(row => {
data.push({
transactionDate: excelDateToJson(row.A),
transactionAccount: row.B,
Category: row.C,
Item: row.D,
Amount: row.E,
transactionType: row.F,
currency: row.G
});
});
return (
<div className="displayData">
<table>
<thead>
<tr>
{keys.map((key) => (
<th>{tableHead[key]}</th>
))}
</tr>
</thead>
<tbody>
{tableBody.map((row) => (
<tr key={row.id}>
{keys.map((key) => (
<td>{row[key]}</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
};
The excel document comes from asp.net web api as a base64string. Thanks in advance!
I made a custom game in discord. It grabs words from a list of words in the scramble-words.json file and scrambles them. Those words get put into a text chat and the user playing the game has to try and find what the actual word is. It'll delete all new messages that get sent since you started the game and keep the channel clean as long as the game is active. You have to type the word and if it's correct you get a point.
The first time the command is run the code runs fine. The second time it gives an error
UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Message with every message you send in the new game.
I've tried looking up if it had to do something with me assigning the games = {} variable as a const but I don't think that's the problem and I can't think of what else it could be.
const { words } = require('./scramble-words.json');
const Discord = require('discord.js');
/*const example = {
channelId: {
message:'message object',
stage: 'string',
counter: 'number',
currentWord: 'string',
remainingWords: ['words here'],
points: {
userId: 'points'
}
}
}*/
const games = {}
const stages = {
'STARTING': (counter, topic) => {
return `-----------------------------**Game**------------------------------\nA new "${topic} Scramble" game is starting in ${counter}s!`
},
'IN_GAME': (word, topic) => {
let scrambledWord = '';
if(topic === "Brawlhalla"){
topic = "Brawlhalla related thing"
}
scrambledWord = shuffle(word);
return `-----------------------------**Game**------------------------------\nWhat ${topic} is this?\n\n **${scrambledWord}**`
},
'ENDING': (points) => {
const sorted = Object.keys(points).sort((a, b) => {
return points[b] - points[a]
})
let embed = new Discord.MessageEmbed();
embed.setTitle('**POINTS**')
.setDescription(`**The game is now over! Here's how everyone did!**`);
var results = `\n`
var firstPlace = points[sorted[0]]
var secondPlace = null
var thirdPlace = null
var leftover = null
for(const key of sorted) {
var amount = points[key]
if(leftover){
results += `<#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
} else if(thirdPlace) {
if(thirdPlace === amount) {
results += `:third_place: <#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
} else {
results += `\n`
results += `<#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
leftover = amount
}
} else if(secondPlace) {
if(secondPlace === amount) {
results += `:second_place: <#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
} else {
results += `\n`
results += `:third_place: <#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
thirdPlace = amount
}
} else if(firstPlace) {
if(firstPlace === amount) {
results += `:first_place: <#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
} else {
results += `\n`
results += `:second_place: <#${key}> had ${amount} point${amount === 1 ? '' : 's'}\n`
secondPlace = amount
}
}
}
if(results === `\n`){
return embed.setTimestamp().addField(`**Nobody got points you losers**`, "🤡");
} else {
return embed.setTimestamp().addField(`**Here's how everyone did**`, results)
}
}
}
const selectWord = (game) => {
game.currentWord = game.remainingWords[Math.floor(Math.random() * game.remainingWords.length)]
const index = game.remainingWords.indexOf(game.currentWord);
game.remainingWords.splice(index, 1);
game.currentWord = game.currentWord.toLowerCase().charAt(0).toUpperCase() + game.currentWord.toLowerCase().substring(1);
}
const gameLoop = async () => {
for(const key in games) {
const game = games[key];
const { message, stage } = game;
const gameLength = 2.345
if(stage === 'STARTING') {
let string = stages[stage](game.counter, game.topic)
message.edit(string)
if(game.counter <= 0) {
game.stage = 'IN_GAME'
game.counter = 60 * gameLength
selectWord(game)
string = stages[game.stage](game.currentWord, game.topic)
message.edit(string)
}
} else if (stage === 'IN_GAME') {
if(game.counter <= 0) {
game.stage = 'ENDING'
if(game.topic === "Brawlhalla")
{
game.topic === "Brawlhalla related thing"
}
const string = `-----------------------------**Game**------------------------------\nThe last ${game.topic} was: ${game.currentWord}\n------------------------------**End**-------------------------------`
message.edit(string)
embed = stages[game.stage](game.points);
message.channel.send(embed)
await delete games[key]
await delete game
return
}
}
--game.counter
}
setTimeout(gameLoop, 1000)
}
module.exports = {
scramble(member, channel, content, guild, message, { reply }, client) {
/*if(!member.hasPermission('ADMINISTRATOR')){
reply(true, `You don't have permission to execute this command!`)
return;
}*/
if(channel.name !== "scramble-games" && channel.name !== "games"){
reply(true, `You can only do this command in a channel called "scramble-games" or "games"`);
return;
}
if(games[channel.id]){
return;
}
message.delete();
var chosenCategory= []
if(content[0]){
if(content[0].toLowerCase() === "pokemon"){
if(content[1]){
var numbers = content[1].split('')
if(!isNaN(content[1])){
for(var i = 0; i < numbers.length; i++){
if(numbers[i] === "1") {
chosenCategory = chosenCategory.concat(pokemonGeneration1)
} else if(numbers[i] === "2") {
chosenCategory = chosenCategory.concat(pokemonGeneration2)
} else if(numbers[i] === "3") {
chosenCategory = chosenCategory.concat(pokemonGeneration3)
} else if(numbers[i] === "4") {
chosenCategory = chosenCategory.concat(pokemonGeneration4)
} else if(numbers[i] === "5") {
chosenCategory = chosenCategory.concat(pokemonGeneration5)
} else if(numbers[i] === "6") {
chosenCategory = chosenCategory.concat(pokemonGeneration6)
} else if(numbers[i] === "7") {
chosenCategory = chosenCategory.concat(pokemonGeneration7)
} else if(numbers[i] === "8") {
chosenCategory = chosenCategory.concat(pokemonGeneration8)
} else {
reply(true, `The numbers you gave had a number that is higher than 8. There are only 8 gens. Try again but keep the numbers you give under 8`)
return;
}
}
} else {
reply(true, `If you want to specify gens you have to give numbers only! example: 1456 will give gens 1, 4, 5 and 6`)
return;
}
} else {
chosenCategory = chosenCategory.concat(pokemonGeneration1, pokemonGeneration2, pokemonGeneration3, pokemonGeneration4, pokemonGeneration5, pokemonGeneration6, pokemonGeneration7, pokemonGeneration8)
}
topics = "Pokemon"
} else if (content[0].toLowerCase() === "brawlhalla" || content[0].toLowerCase() === "brawl"){
chosenCategory = chosenCategory.concat(BrawlhallaLegends, BrawlhallaWeapons, BrawlhallaWords, BrawlhallaColors, BrawlhallaStances, BrawlhallaChests, BrawlhallaGamemodes)
topics = "Brawlhalla"
} else {
reply(true, `That's not a valid topic for this game!`);
return
}
} else {
chosenCategory = words
topics = "Random Word"
}
channel.send('Preparing Game...').then((message) => {
games[channel.id] = {
message,
stage: 'STARTING',
counter: 10,
remainingWords: [...chosenCategory],
points: {},
topic: topics
}
});
gameLoop(channel)
client.on('message', message => {
const { channel, content, member } = message;
const { id } = channel
const game = games[id];
if(game && game.currentWord && !member.user.bot) {
checkWord(game, member, message, content);
}
if (game && !message.author.bot) {
message.delete();
}
return;
});
}
}
function checkWord(game, member, message, content){
if(game.stage === 'IN_GAME' && content.toLowerCase() === game.currentWord.toLowerCase()) {
const owo = game.currentWord;
game.currentWord = null;
const seconds = 3;
const { points } = game
points[member.id] = points[member.id] || 0
message.reply(`You got it!\n The correct answer was: **${owo}**\n +1 point (${++points[member.id]} total)`).then(newMessage => {
newMessage.delete({
timeout: 1000 * seconds
});
});
setTimeout(() => {
if(game.stage === 'IN_GAME') {
selectWord(game)
const string = stages[game.stage](game.currentWord, game.topic)
game.message.edit(string);
}
}, 1000 * seconds);
}
}
function shuffle(word) {
var wordArray = word.split(' ');
var output = []
for(var i = 0; i < wordArray.length; i++) {
var array = wordArray[i].split('');
var currentIndex = array.length;
var temporaryValue;
var randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
output = output.concat(array)
if(!i + 1 === wordArray.length){
output.push(' ');
}
}
return output.join('');
}
Here's the json file too so you can try out the game yourself
{
"words": [
"Provincial",
"Grudge",
"Foundation",
"Carry",
"Fight",
"Belt",
"Perforate",
"Obstacle",
"Hide",
"Lesson",
"Car",
"Building",
"Mourning",
"Debut",
"Sunrise",
"Scatter",
"Clash",
"Equation",
"Performer",
"Ask",
"Butterfly",
"Medieval",
"Think",
"Minimum",
"Play",
"Sofa",
"Minority",
"Friend",
"Protect",
"Mess",
"Disability",
"Planet",
"Federation",
"Film",
"Vegetarian",
"Utter",
"Polish",
"Ankle",
"Calendar",
"Extreme",
"Student",
"Barrier",
"Motif",
"Solo",
"Toast",
"Steel",
"Speaker",
"Concede",
"Suit",
"gimping",
"Weal",
"Affords",
"Palship",
"Trefoil",
"Kirtled",
"Jaybirds",
"Shires",
"Gobbling",
"Puffery",
"Bag",
"Idoneous",
"Aerates",
"Kitchens",
"Zorils",
"Students",
"Idles",
"Howe",
"Veenas",
"Airship",
"Olefins",
"Munsters",
"Polemics",
"Lentos",
"Snog",
"Fusel",
"Giglot",
"Pinafore",
"Snowiest",
"Saxtuba",
"Division",
"Mantlet",
"Nurtures",
"Geoponic",
"Civvies",
"Trommels",
"Engraver",
"Know",
"Gummoses",
"Disbands",
"Parse",
"Donator",
"Minces",
"Lofted",
"Punters",
"Lie",
"Rune",
"Dottiest",
"Mib",
"Enwraps",
"Bizzes",
"Nitride",
"Ire",
"Bricole",
"Bigness",
"Roadeos",
"Midriffs",
"Fallers",
"Postcode",
"Sterigma",
"Duvetyne",
"Alumroot",
"Purins",
"Pricking",
"Deluders",
"Postcoup",
"Daggas",
"Rallies",
"Vocably",
"Gravida",
"Eluded",
"Dicyclic",
"Starers",
"Afflatus",
"Misbind",
"Coadmire",
"Overrule",
"Marquis",
"Pogromed",
"Dulled",
"Lantana",
"Garotte",
"Keek",
"Dhak",
"Mescals",
"Trichite",
"Theurgic",
"Cretins",
"Codicils",
"Depside",
"Cadres",
"Desium",
"Indene",
"Depicted",
"Opticist",
"Hoptoad",
"Jacking",
"Girasole",
"Wedeln",
"Pull"
]
}
Unknown message errors occur when you delete a message, then try and fetch that message, or use it in a method. I can see 2 message#delete methods in your code, and these is nearly always that cause of these errors. Go through your code and find where you are deleting the messages, and make sure you are not using anything to do with that message afterwards. The post here displays how these errors occur.
I can see one reason this error would throw, if you are iterating through the games, you use message#delete in the first game and the program runs fine, then in all of the other iterations it throws that error. This is because the message#delete is trying to delete an already deleted message (i.e. when you first deleted it in the first game).
I have this json reponse :
id: 30
tableName: "UserCredit"
keyValues: "{"Id":39}"
oldValues: "{"CoinLastUpdate":"2020-02-18T14:18:13.5155426+00:00","ScoreLastUpdate":"2020-02-18T14:18:13.5155429+00:00"}"
newValues: "{"CoinLastUpdate":"2020-02-18T14:18:15.7325823+00:00","ScoreLastUpdate":"2020-02-18T14:18:15.7325826+00:00"}"
auditType: "Update"
createdOnUtc: "2020-02-18T14:18:15.7338989Z"
createdByRefId: 39
I want to find the difference between oldValues and newValues then I write this code :
setOldNewValue(item: DeiffrentModel): void {
let oldValue;
let newValue;
console.log(item.oldValues)
if (item.newValues !== null) {
newValue = item.newValues.split(',');
}
if (item.oldValues !== null) {
oldValue = item.oldValues.split(',');
}
for (let index = 0; index < newValue.length; index++) {
let addModel = {} as DeifferModel;
addModel.field = 'id';
addModel.newValue = newValue[index];
console.log(oldValue)
if (oldValue !== undefined) {
addModel.oldValue = oldValue[index]
}
this.differModel.push(addModel);
}
this.findDiffrent = _.difference(newValue, oldValue);
}
Now I have this problem :
**** I create in newValue and oldValue array of value but it shows like this :
0: "CoinLastUpdate":"2020-02-18T14:18:13.5155426+00:00"
1: "ScoreLastUpdate":"2020-02-18T14:18:13.5155429+00:00"}
but I need just 2020-02-18T14:18:13.5155429+00:00
How can I solve this problem?
You should use JSON structure instead of parsing a string manually.
I would also use DeifferModel as a class instead of an interface, so you can init items more easily:
// in a xxx.model.ts file
export class DeifferModel {
constructor(public field, public newValue, public oldValue) {}
}
// in your component
setOldNewValue(item: DeiffrentModel): void {
if (item.newValues) {
newValue = JSON.parse(item.newValues);
}
if (item.oldValues) {
oldValue = JSON.parse(item.oldValues);
}
Object.keys(newValue).foreach(key => {
const addModel = new DeifferModel('id', newValue[key], oldValue[key]);
this.differModel.push(addModel);
});
this.findDiffrent = _.difference(newValue, oldValue); // no use of "this.differModel" ?
}
Insteading of storing these as an array, parse the values to an object
if (item.newValues !== null) {
newValue = item.newValues.split(',');
}
if (item.oldValues !== null) {
oldValue = item.oldValues.split(',');
}
to
oldValue = JSON.parse(oldValues);
newValue = JSON.parse(newValues);
You can find the difference in milliseconds like this:
CoinLastUpdateDiff = Math.abs(new Date(newValue.CoinLastUpdate) - new Date(oldValue.CoinLastUpdate));