javascript array function can't be used - javascript

below is a piece of js code.When I run it with "node" command. It displays. "notes.filter" is not a function.If I comment "JSON.parse" line. It works. But video tutorial does have this line. So I am quite confused here. Could any one helps here. Thanks a lot.
var addNote = (title, body) => {
var notes = [];
var note = {
title,
body
}
try {
var notesstring = fs.readFileSync('notes-data.json');
notes = JSON.parse(notesstring);
} catch (e) {
}
console.log(Array.isArray(notes));
var duplicateNote = notes.filter((note) => note.title === title);
if (duplicateNote.length === 0) {
notes.push(note);
fs.writeFileSync('notes-data.json', JSON.stringify(note));
}
};

I had the same problem while going through the course but ended up fixing it.
For some reason, I was getting back bad JSON, and so I had to delete the note-data.json file, and then re-run the app. This fixed it for me!

Related

Dynamic help command discord.js

I'm currently making a discord bot but I have an issue. I'm still quite new to discord.js and node.js. This is my code:
module.exports.run = async (bot, message, args) => {
function getMenu() {
var hpmenu = {};
return new Promise(function(resolve, reject) {
dashboard.readServerBoundValue(
`${message.guild.id}`,
'PREFIX',
async function(output) {
if (output) {
var prefixxx = output;
} else {
var prefixxx = config.botPrefix;
}
//=====================================================================================================
fs.readdir('./src/commands/', (err2, files2) => {
files2.forEach((f2, i2) => {
hpmenu[f2] = new discord.MessageEmbed();
hpmenu[f2].setTitle(`${f2}`);
console.log('Added catagory ' + f2);
//=========================================================================================
fs.readdir(`./src/commands/${f2}`, (err, files) => {
files.forEach((f, i) => {
const cmd = f.replace('.js', '');
hpmenu[f2].addField(cmd, 'test');
console.log('Added command ' + cmd);
//=====================================================================================================
});
resolve(hpmenu);
});
});
});
}
);
});
}
async function main() {
var output = await getMenu();
message.channel.send(output['developer']);
}
main();
};
This code doesnt have any errors but this is the issue I'm having:
The issue is that it runs the main function before it finished the getMenu function.
How to solve this? I have read multiple posts about this. Thanks for reading everyone!
After alot of coding i reached my goal; Making a dynamic help menu with pagination.
This is the code:
https://pastebin.com/QGVfutti
It functions good. The only thing you need is to make a file named config.json in the root directory of the bot where index.js is located and add a key named "embedColor" put your commands in
./src/commands/CATAGORY/COMMAND.js
and this is the result:
sorry for bad english. Do note if you use it you still have to implement the prefix and description yourself this depends per command handler and database engine.
You can change the description code and the command name at line 19 in the pastebin. if you want a image you can add a new line after line 13:
hmu[i].setImage("IMAGE");
Its just a discord embed and it will work fine, add thumbnails, authors, and change however you like. You do not have to credit me if you're using it
Sorry for my bad english and a thank you to Lioness100 for editing the text. English is not my first language :) Have a nice day everyone bye!

Issues updating firestore document by committing a batch after an async function

I'm writing a cloud function that uses request-promise and cheerio to scrape a website and then check that information against a user document.
I am not entirely familiar with Javascript and Cloud Functions.
I've come so far that I managed to extract the information I need and navigate to the user's document and compare the data. Now the last piece of this function is to give the user points for each matching data point, so I need to update a map inside the user document.
This function has to loop through all users and change their document if the data point matches. I'm not sure the way I've written the code is the most optimal in terms of performance and billing if the userbase gets huge... Any pointers to how I could minimize the impact on the task would be of great help, as im new with JS.
So this is the code:
exports.getV75Results = functions.pubsub.schedule('every 2 minutes').onRun(async (context) => {
let linkMap = new Map();
const url = `https://www.example.com`
const options = {
uri: url,
headers: { 'User-Agent': 'test' },
transform: (body) => cheerio.load(body)
}
await rp(options)
.then(($) => {
for(let i = 1; i <= 7; i++)
{
//Find player from game
const lopp1 = $(`#mainContentHolder > div > div.mainContentStyleTrot > div > div.panel-body > table:nth-child(1) > tbody > tr:nth-child(${i}) > td:nth-child(2) > span`).text()
const lopp1StrR1 = lopp1.replace("(", "");
const lopp1StrR2 = lopp1StrR1.replace(")", "");
const lopp1StrR3 = lopp1StrR2.replace(" ", "");
linkMap.set(i, lopp1StrR3.toUpperCase());
}
console.log(linkMap);
return linkMap;
}).then(async () => {
//Start lookup users
let usersRef = db.collection('fantasyfotball').doc('users');
usersRef.listCollections().then(collections => {
collections.forEach( collection => {
var user = collection.doc(collection.id);
let batch = new admin.firestore().batch();
user.get().then(function(doc) {
let json = doc.data();
//Look in users collection if players document exist
Object.keys(json).forEach((name) => {
if(name != null) {
//Document with users active fotball players
if(name == 'players') {
let i = 0;
Object.values(json[name]).forEach((value) => {
i++;
if(value.localeCompare(linkMap.get(i)) == 0) {
//Loop through user keys and find owned players if user has the correct player
Object.keys(json).forEach((map) => {
if(map != null)
{
//Document with a map of player owned fotball players, each respective player has a key = 'fotball player' and value = '[price, points]'
if(map == 'ownedplayers')
{
Object.entries(json[map]).forEach((players) => {
if(players[0].localeCompare(value) == 0) {
console.log(players[1][1]);
//Add points to respective player field
//PROBABLY NOT HOW TO CHANGE A DOCUMENT FILED, THIS DOESNT WORK..
players[1][1]++;
}
});
//EACH TIME THIS RUNS IT SAYS: "Cannot modify a WriteBatch that has been committed"
batch.update(user, {'ownedplayers': json[map]});
}
}
});
}
});
}
} else {
console.log('user does not have a playermode document.');
}
});
});
return batch.commit().then(function () {
console.log("Succesfully commited changes.");
return null;
});
});
});
}).catch((err) => {
return err;
});
});
The issues i get in the console are "Cannot modify a WriteBatch that has been committed." and I fail to modify and add points to the player field inside the users document.
This is the console:
This is the firestore document structure:
I'm completely stuck on this.. Feels like I've tried all different approaches, but I think i dont fully understand cloud functions and javascript, so i would gladly recive feedback and help on how to make this work.
Cheers,
Finally.... i managed to update the document successfully. I put the commit outside another ".then()". Thought I tried that, but yay I guess :P
}).then(() => {
return batch.commit().then(function () {
console.log("Succesfully commited changes.");
return null;
});
The problem now is that it commits every loop. I think the most optimal here would be to batch update ALL users before committing?
And again, is there a more optimal way to do this, in terms of minimizing the operation and impact? I'm afraid I go too deep with for loops instead of directly navigating to the document, but haven't found an easier way to do that.
Any thoughts?

webkitGetAsEntry object delay

I'm trying to read the directory structure of a dropped folder, however I am having an issue with chrome not reporting the correct amount of items in the object without me adding a delay.
It doesn't make any sense to me that the object can lose an item between the first and second logging and then gain it back for the third logging.
Any help would be much appreciated.
UPDATE: I did some more testing and have found that even copying values from an existing array instead of reading the file structure I still get the same issue.
Here is a jsfiddle showing the issue more clearly.
This seems to be almost the solution, However in both cases they fire multiple times if I drag multiple sub folders instead of the parent folder. I want to be able to drag a folder of sub folders or a selection of the sub folders and have the event just fire once at the end, so basically at the end of the for loop.
// Works correctly
console.log(itemList);
// Doesn't log anything
Object.keys(itemList).forEach(function(key)
{
console.log('where is this?', key, itemList[key]);
});
// Works correctly on my local server with 0ms delay
// and on jsfiddle with 50ms
setTimeout(function()
{
Object.keys(itemList).forEach(function(key)
{
console.log('ms delay', key, itemList[key]);
});
},50);
OK, I found a working solution eventually.
My jsfiddle based on this answer
const target = document.getElementById('dropTarget');
let itemList = [];
target.ondragover = function(evt) {
evt.preventDefault();
}
target.ondrop = function(e) {
e.preventDefault();
let items = e.dataTransfer.items;
function scanFiles(item, index) {
return new Promise(function(resolve) {
if (item.isFile) {
itemList.push(item.fullPath);
resolve();
} else if (item.isDirectory) {
let directoryReader = item.createReader();
directoryReader.readEntries(function(entries) {
Promise.all(entries.map(scanFiles)).then(resolve);
});
}
})
}
var p = Promise.all(Array.from(items, item => scanFiles(item.webkitGetAsEntry())));
p.then(function() {
//console.log(itemList);
Object.keys(itemList).forEach(function(key) {
console.log(key, itemList[key]);
});
})
}

Word add-in: Get whole document but File.getSliceAsync method not returning

I'm creating an Office Add-in and am having trouble with the javascript file.getFileAsync method in Word Online (Word 2013 desktop is fine).
I'm using sample code from github...
https://github.com/OfficeDev/office-js-docs/blob/master/docs/word/get-the-whole-document-from-an-add-in-for-powerpoint-or-word.md
My code looks like this...
function getFile() {
Office.context.document.getFileAsync(Office.FileType.Text,
{ sliceSize: 65536},
function (result) {
if (result.status == Office.AsyncResultStatus.Succeeded) {
// Get the File object from the result.
var myFile = result.value;
var state = {
file: myFile,
counter: 0,
sliceCount: myFile.sliceCount
};
getSlice(state);
}
});
}
function getSlice(state) {
state.file.getSliceAsync(state.counter, function (result) {
if (result.status == Office.AsyncResultStatus.Succeeded) {
sendSlice(result.value, state);
state.file.closeAsync();
}
else if(result.status == 'failed')
state.file.closeAsync();
});
}
Before calling file.getSliceAsync the data looks good - myFile.sliceCount is 1. The result function is never called and no errors are thrown in the console.
Thanks for any help you can provide!
UPDATE: this issue is fixed and live. Please try it again it must work now.
thanks!
---------------- ORIGINAL ANSWER JUST FOR REFERENCE ----------------------------
Yes, there is a regression right now in Word Online preventing the code to run successfully. The specific issue is that the file.getSliceAsync method is never calling the call-back function. This only happens with the TEXT type, if you want to get the docx or pdf this should work ok. This issue will be fixed in a couple of weeks.
You have an alternative if you want to get the text of the document you can use the new APIs for Word check out this sample:
Word.run(function(context) {
var myBody = context.document.body;
context.load(myBody);
return context.sync()
.then(function(){
console.log(myBody.text);
});
});
Hope this helps!
Thanks for reporting this issue!
Juan.

Twitter bot image posting bug

Ok so I've had a lot of fun setting up a twitterbot through these tutorials and I have had no problems up to image posting. I have been following along these tutorials: https://www.youtube.com/playlist?list=PLRqwX-V7Uu6atTSxoRiVnSuOn6JHnq2yV and was stuck on 15.6 (https://www.youtube.com/watch?v=mUoIPmZ4KwA) where we post images. It's takes kind of a while to watch all of it but you might be able to skip the simple tweeting text and follow response videos. Now, I understand about 80% of what this guy is saying, as I am a little new to JS compared to some of you guys who are much more experienced than me, so some of my code is a little repetitive, but I wanted to make sure everything runs.
var imageTweet = function(txt) {
var tweet = {
status:txt
}
//This is for uploading the image to twitter but not actually tweeting it
//Might want to define the b64_img
var b64_img = 0;
var imageProcessing = function(){
var filename = "dankykang.jpg";
var params_img = {
encoding:'base64'
}
b64_img = fs.readFileSync(filename, params_img)
}
imageProcessing();
var upload_params = {
media_data: b64_img
}
T.post('media/upload', upload_params, tweeted_img);
function upload_img(err, data, response){
//This part does the tweet
var id = data.media_id_string;
var tweet = {
//for text in the image tweet
status:"testing a new way to tweet an image...",
//This calls the image from the imageProcessing function
media_ids:[id]
}
T.post('statuses/update', tweet, imgstatustweeted);
function imgstatustweeted(){
if (err){
console.log("The status didn't work")
} else {
console.log("Status worked")
}
}
imgstatustweeted();
}
upload_img();
function tweeted_img(err, data, response){
if (err){
console.log("Image not posted");
} else {
console.log("Image posted");
}
}
tweeted_img();
}
imageTweet();
I follow most of his steps with some name changes, and I don't think I am missing anything... but when I run bot.js it keeps giving me an error on data.media_id_string; [above var tweet = {...} and below function upload_img(...)]
it says TypeError: Cannot read property 'media_id_string' of undefined. But according to the tutorial I'm following, I think this has to to with the npm which was set up. So I don't know why it runs fine on his end but doesn't run fine on my end. If I'm not mistaken its not a syntax problem.

Categories

Resources