new data added to JSON keeps replacing previous - node.js

It seems like "notes = JSON.parse(fs.readFileSync("notes-data.json"))" line of my code is not working as it should...
When I add new notes it should add on to the array in the .json file, but it just replaces the previous note.
let addNote = (title, body) => {
let notes = [];
let note = {
title,
body
};
notes.push(note);
fs.writeFileSync("notes-data.json", JSON.stringify(notes));
notes = JSON.parse(fs.readFileSync("notes-data.json"))
};
Code Screenshot:
Thank you in advance

If you want to add to the file contents, then you should really read the content before doing anything else:
let addNote = (title, body) => {
let notes;
try {
notes = JSON.parse(fs.readFileSync("notes-data.json")); // <---
} catch(e) {
notes = [];
}
let note = {
title,
body
};
notes.push(note);
fs.writeFileSync("notes-data.json", JSON.stringify(notes));
};

Related

Unable to run includes() method on string returned by fs.readFileSync()

having a bit of trouble:
let data = fs.readFileSync(pathToCsv, "utf8");
the value of data comes out to be:
clan,mem1,mem2,mem3,mem4,language,managerID,serverJoinedDate
pm,
pm
(through console.log())
but still data.toString().includes("pm") is false.
Here is my full code:
const filter = (m) => m.author.bot === false;
await ogMessage.author.dmChannel
.awaitMessages(filter, {
max: 1,
time: 60000,
})
.then((collected) => {
if (clans[parseInt(collected.toJSON()[0].content) - 1]) {
let clan = clans[parseInt(collected.toJSON()[0].content) - 1];
let data = fs.readFileSync(pathToCsv, "utf8");
console.log(typeof clan);
// let reg = new RegExp(clan, "g");
// let count = (data.match(reg) || []).length;
if (data.split(",").includes(clan)) {
ogMessage.author.send(
"People from this clan are already registered!\nPlease contact the hosts for help!"
);
return;
} else {
teamCheck = true;
}
} else {
ogMessage.author.send("Invalid Clan! Please try again!");
return;
}
})
.catch((collected) => {
try {
console.log("Error" + collected);
} catch (e) {
console.log(e);
}
});
if (teamCheck === false) {
return;
}
I have tried splitting the data, using regular expressions but nothing seems to work on the string returned by
readFileSync()
PS. I am making a discord bot.
In the source string you have pm with a space before it. That's why after calling split("," you end up with the element " pm" in the result array and "pm" is not equal to it.
You just need to trim spaces in all elements before searching some string in it
The problem was in the clans array.
I was defining it as such:
var clans = fs.readFileSync(pathToData, "utf8").split("\n");
but the problem was that the readFileSync() method added an "\r" after every string of the array. That is why it was not able to match the clan string to the data
So what worked was var clans = fs.readFileSync(pathToData, "utf8").split("\r\n");
Now, the array includes only the string, and the includes() method can find a match!

How do I get these properties to not be undefined when they're in an embed

const Discord = require('discord.js')
const prefix1 = '*add'
const prefix2 = '*what'
const prefix3 = '*remove'
const prefix4 = '*search'
const bot4 = new Discord.Client();
let a = []
let fakea = []
bot4.on('message', msg => {
if(msg.member.hasPermission('ADMINISTRATOR')){
if(msg.content.startsWith(prefix1)){
let splited = msg.content.split(' ')
let unchanged = msg.content.split(' ')
splited.splice('*info', 1)
splited.splice(msg.content[1], 1)
splited.splice(msg.content[2], 1)
let c = splited.join(' ')
b = {
namer: unchanged[1],
imformation: unchanged[2],
description: c
}
if(fakea.includes(unchanged[1])){
msg.channel.send('It already exists')
} else {
a.push(b)
fakea.push(unchanged[1])
}
console.log(a)
}
if(msg.content.startsWith(prefix3)){
let armay = msg.content.split(' ')
console.log(a)
console.log(fakea)
if(armay.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *add on it's own or you had more than one word that you put with the command`)
} else {
if(!fakea.includes(armay[1])){
msg.channel.send(`That doesn't exist. You can't delete something that doesn't exist.`)
} else {
let fakeafind = fakea.find(plot => plot === armay[1])
let afind = a.find(plote => plote.namer === armay[1])
fakea.splice(fakeafind, 1)
a.splice(afind, 1)
}
console.log(a)
console.log(fakea)
}
}
if(msg.content.startsWith(prefix2)){
let coolon = fakea.join('\n')
let don = `_________\n[\n${coolon}\n]\n_________`
const notbot3embed = new Discord.MessageEmbed()
.setTitle('Everything you can search')
.setColor('15DD7C')
.addField('The things you can search', don)
msg.channel.send(notbot3embed)
}
if(msg.content.startsWith(prefix4)){
let mayi = msg.content.split(' ')
if(mayi.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *search on it's own or you had more than one word that you put with the command`)
} else {
if(fakea.includes(mayi[1])){
let ft = a.filter(thing => thing.namer === mayi[1])
console.log(ft)
let secot = ft.namer
let thirt = ft.imformation
let fort = ft.description
const someembed = new Discord.MessageEmbed()
.setTitle(secot)
.setColor('FF4200')
.addField(thirt, fort)
msg.channel.send(someembed)
} else {
msg.channel.send('This is not a searchable term. Use *what to see the terms that are there.')
}
}
}
}
})
bot4.login(process.env.token4)
I wrote all of it because you would be confused about the properties if I didn't. In the last part I try to get the properties of the object with the name after '*search'. Then I want to put it an embed. Here's the problem I get. On the embed all three of the things say undefined. How do I fix this
If you're confused what I'm trying to do here's what I'm trying to do. I'm trying to make a system that you can put search things(I don't know how to frase it), remove them, check which ones exist and search something. Most of it is working. But in the search part it says for all of them in the embed undefined.
I found out that you need to use find instead of filter. Find works.

Gmail to Google Spread Sheet (only date, email and subject)

The code I have cobbled together does work, but it imports the wrong things from my email. I only want the date sent, the sender email address and the subject to import into the google sheet.
Can anyone help?
function onOpen() {
const spreadsheet = SpreadsheetApp.getActive();
let menuItems = [
{name: 'Gather emails', functionName: 'gather'},
];
spreadsheet.addMenu('SP LEGALS', menuItems);
}
function gather() {
let messages = getGmail();
let curSheet = SpreadsheetApp.getActive();
messages.forEach(message => {curSheet.appendRow(parseEmail(message))});
}
function getGmail() {
const query = "to:legals#salisburypost.com";
let threads = GmailApp.search(query,0,10);
let messages = [];
threads.forEach(thread => {
messages.push(thread.getMessages()[0].getPlainBody());
label.addToThread(thread);
});
return messages;
}
function parseEmail(message){
let parsed = message.replace(/,/g,'')
.replace(/\n*.+:/g,',')
.replace(/^,/,'')
.replace(/\n/g,'')
.split(',');
let result = [0,1,2,3,4,6].map(index => parsed[index]);
return result;
}
I believe your goal as follows.
You want to retrieve "the date, sender and subject" from the 1st message in the searched threads to the active sheet of Google Spreadsheet.
For this, how about this answer?
Modification points:
In this case, you can retrieve "the date, sender and subject" using the built-in methods for GmailApp.
When the values are put to the Spreadsheet, when appendRow is used in the loop, the process cost will become high.
It seems that label is not declared in your script.
When above points are reflected to your script, it becomes as follows.
Modified script:
In this modification, I modified gather() and getGmail() for achieving your goal.
function gather() {
let messages = getGmail();
if (messages.length > 0) {
let curSheet = SpreadsheetApp.getActiveSheet();
curSheet.getRange(curSheet.getLastRow() + 1, 1, messages.length, messages[0].length).setValues(messages);
}
}
function getGmail() {
const query = "to:legals#salisburypost.com";
let threads = GmailApp.search(query,0,10);
let messages = [];
threads.forEach(thread => {
const m = thread.getMessages()[0];
messages.push([m.getDate(), m.getFrom(), m.getSubject()]);
// label.addToThread(thread);
});
return messages;
}
When no threads are retrieved with "to:legals#salisburypost.com", the values are not put to the Spreadsheet. Please be careful this.
References:
getDate()
getFrom()
getSubject()
setValues(values)

How to delete items attachement from sharepoint List using pnpjs?

Hi Im trying to delete attached item from list items first and then upload new attach file in sharepoint using pnp js (in vuejs)!
i trace the code and delete part is runnging but i dont konw why attached file doesnt delete!!!
this is my code for deleting attached item
public async DeleteItemsAttachment(itemId: number): Promise<any> {
let item = pnp.sp.web.lists.getById('{128EF67A-FDSF-4F42-8E8F-D3FC9523273E}').items.getById(itemId)
return await item.attachmentFiles.deleteMultiple()
}
public async AddanAttachment(itemId: number, fileName: string, arrayBuffer: File): Promise<any> {
let item = pnp.sp.web.lists.getById('{128EF6AA-FD8F-4F42-8E8F-D3FC9523273E}').items.getById(itemId)
return await item.attachmentFiles.add(fileName, arrayBuffer)
}
uploadFile(){
if (this.itemId != null && this.myfiles) {
if (this.HasUploadFile) {
this.spService.DeleteItemsAttachment(this.itemId).then(response => {
this.AddAnAttachmentToRecord()
}).catch(e => {
this.message = ` exception : ${e}`
})
}
else {
this.AddAnAttachmentToRecord()
}
}
How can i solve my problem?
where is wrong area of my code?
According to attachmentfiles.ts deleteMultiple function expects the array of attachment file names, so attachments could be deleted by explicitly providing file names:
item.attachmentFiles.deleteMultiple("{attachment-file-name-1}","{attachment-file-name-2}")
or (more dynamic way) by reading attachment names and specifying it in deleteMultiple function:
let item = sp.web.lists.getByTitle(listTitle).items.getById(itemId);
//1. get all attachments
let attachments = await item.attachmentFiles.get();
let attachmentNames = attachments.map(a => a.FileName);
//2. delete all attachmanents
await item.attachmentFiles.deleteMultiple(...attachmentNames);

Delete filled in details after restart

I'm trying to let a person fill in some details and return an overview of the details. There is an option to restart the conversation (look at code) but when the conversation is restarted and the person fill in some new details, it will show the old details of the first filled in details.
How can i fix this problem ?
bot.dialog('overview', function (session, options) {
if (session.message && session.message.value) {
if(session.message.value.actions == "Accept"){
}
return;
}
var overview_msg = require('./cards/overview.json');
var date = new Date();
overview_msg.attachments[0].content.body[0].items[1].columns[1].items[0].text = overview_msg.attachments[0].content.body[0].items[1].columns[1].items[0].text.replace(/{{name}}/,nameGuest)
overview_msg.attachments[0].content.body[0].items[1].columns[1].items[1].text = overview_msg.attachments[0].content.body[0].items[1].columns[1].items[1].text.replace(/{{date}}/,date.toDateString() +' ' + date.toLocaleTimeString());
overview_msg.attachments[0].content.body[1].items[1].facts[0].value = overview_msg.attachments[0].content.body[1].items[1].facts[0].value.replace(/{{email}}/, mailGuest);
overview_msg.attachments[0].content.body[1].items[1].facts[1].value = overview_msg.attachments[0].content.body[1].items[1].facts[1].value.replace(/{{phone}}/, phoneGuest);
overview_msg.attachments[0].content.body[1].items[1].facts[2].value = overview_msg.attachments[0].content.body[1].items[1].facts[2].value.replace(/{{extra}}/, numberPeople);
overview_msg.attachments[0].content.body[1].items[1].facts[3].value = overview_msg.attachments[0].content.body[1].items[1].facts[3].value.replace(/{{lunch}}/, lunchGuest);
overview_msg.attachments[0].content.body[1].items[1].facts[3].value = overview_msg.attachments[0].content.body[1].items[1].facts[3].value.replace(/{{allergy}}/, lunchAllergyGuest);
overview_msg.attachments[0].content.body[1].items[1].facts[3].value = overview_msg.attachments[0].content.body[1].items[1].facts[3].value.replace(/{{vegan}}/, lunchVegan);
session.send(overview_msg);
bot.dialog('restart', function (session) {
session.beginDialog('overview');
}).triggerAction({matches: /restart|quit/i});
I think it may relate to how you define variables nameGuest, mailGuest, phoneGuest, etc which are not shown in your code snippet.
For getting values from Input.Text of adaptive-card, you can try the following code snippet:
bot.dialog('form', [
(session, args, next) => {
let card = require('./card.json');
if (session.message && session.message.value) {
next(session.message.value)
} else {
var msg = new builder.Message(session)
.addAttachment(card);
session.send(msg);
}
},
(session, results) => {
// Get the User input data here
session.send(JSON.stringify(results));
}
]).triggerAction({
matches: ['form', 'Action.Submit']
})
Yes i managed to get it done.
Instead of replacing the value in the json i referred to the variable.
example:
overview_msg.attachments[0].content.body[1].items[1].facts[0‌​].value = VARIABLE

Resources