JavaScript & monk: turn result from find() to array - javascript

I am working on an assignment that required us to fetch data of newsfeeds from a MongoDB database using monk. And put them onto a webpage. I am planning to get the data needed in an array. But when I run this, it responses
newsList.find(...).toArray is not a function
I have searched for a solution for that for a while. And I can't really find one.
app.get('/newsfeed.html', function(req, res){
var db = req.db;
var newsList = db.get('newsList');
var newsArray = newsList.find({}, ['-_id', 'headline', 'date', 'content', '-comments']).toArray();
var response = "";
for (let i = 0; i < newsArray.length; i++){
response += newsArray[i];
}
res.send(response);
});

Related

Handling chunks of Data from Node/Express Backend using React/Fetch

I created an Express Backend which sends JSON data as a chunk of text using res.write(JSON.stringify(JSONChunk)).
I want to handle and process each chunck of res.write in react front end and am using the following method:
My Backend pseudo code
for(let i = 0; i < slices; i ++) {
var JSONChunck = await getData(i); // getData operation can take some time
res.write(JSON.stringify(JSONChunck));
}
res.end();
FE pseudocode:
fetch(API, OPTS).then(async (response) => {
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
var text = new TextDecoder("utf-8").decode(value);
var result = JSON.parse(text);
var processedResult = process(result);
}
})
However, when I try the above code in some systems, I receive an error when trying to do JSON.parse(text) and see that the value of 'text' does not fetch full JSON string and only a partial string.
I was wondering if I am doing anything wrong or if there is any better way to do the above.
Any help/suggestions appreciated.
Thank you!

Why won't my server read my json file completely?

I made a get request in a function for fav.json and programmed the id="fav_button" button to run the function, and I set up an express server. However, when I click the button, it only displays the last item in the json file. The json file being fetched is an array of objects.
I have tried using .send instead of .json as well as .sendFile. I have tried debugging the json file, but there are no issues. I have tried using jquery instead, but it makes no difference.
// script.js
function get_fav(e) {
if (!e) {
e = window.event;}
el = e.target || e.srcElement;
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (xhr.status === 200) {
let list = JSON.parse(xhr.response);
for (var i in list) {
let hold = fav_tem;
hold = hold.replace('%title', list[i].song);
hold = hold.replace('%artist', list[i].artist);
hold = hold.replace('%mood', list[i].mood);
document.getElementById('faves_field').innerHTML = hold;}}};
xhr.open('GET', 'fav.json', true);
xhr.send();}
const fav_el = document.getElementById('fav_button');
if (fav_el.addEventListener) {
fav_el.addEventListener('click', get_fav, false);}
else {fav_el.onclick = get_fav;}...
// app.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const fs = require('fs');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res) {
res.send(fs.readFileSync('public/index.html'));
});
app.get('public/fav.json', function(req, res) {
res.json(fs.readFileSync('public/fav.json'));
});...
...app.listen(3003, function() {
console.log('Server started on port 3003...');
});
My script is supposed to request fav.json and append each part of the object to the blue boxes like this: (in bold) Song - artist. Mood: mood(s). My app is supposed to listen for the request for public/fav.json, then send it.
However, for some reason, when I click the allocated button, it only displays the last object of the json file in the blue box below. Here's a link to the full project (I am not very experienced with web developement): https://github.com/YungLonk/Practice-Node-JS. What am I missing or doing wrong?
You're looping over the list, and then setting the html. This is always going to set it to the last item in list.
for (var i in list) {
let hold = fav_tem;
hold = hold.replace('%title', list[i].song);
hold = hold.replace('%artist', list[i].artist);
hold = hold.replace('%mood', list[i].mood);
document.getElementById('faves_field').innerHTML = hold;
};
You should put the variable that holds the data and the html property outside of the loop
let hold = fav_tem;
for (var i in list) {
hold = hold.replace('%title', list[i].song);
hold = hold.replace('%artist', list[i].artist);
hold = hold.replace('%mood', list[i].mood);
};
document.getElementById('faves_field').innerHTML = hold;
EDIT:
I have just had a quick look over your project and I see that fav_tem has only one item (in my head I was thinking that it contains a number of them).
So once you do the replace, then that's it. It can't replace it again because the text is no longer there.
So in that case you would want to append. See below:
let favitems = "";
for (var i in list) {
let hold = fav_tem;
hold = hold.replace('%title', list[i].song);
hold = hold.replace('%artist', list[i].artist);
hold = hold.replace('%mood', list[i].mood);
favitems = favitems + "<br />" + hold;
};
document.getElementById('faves_field').innerHTML = favitems;
Let me know how that goes, I believe that is what you're looking for.

Iteratively Adding Item in separate JS file to an HTML/EJS table in rows - Using NodeJS

I have a function defined in a file called database.js whenever a certain page is loaded. An associated page is loginpage.ejs, which starts with a blank table element.
In this function in database.js, I retrieve values from DynamoDB in a loop, parsing each entry using the JSON parse function.
Here is the function.
var get_restaurants = function(route_callbck){
var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var async = require('async');
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "restaurants"
};
var count = 0;
docClient.scan(params).eachPage((err, data, done) => {
if (data != null) {
for (let index = 0; index < data.Items.length; index++) {
const element = data.Items[index];
var str = JSON.stringify(element);
var x = JSON.parse(str);
//var x is the whole item- how do I put this in a table?
console.log(x);
}
}
done();
});
};
I have an ejs file with a table defined as shown. loginpage.ejs
<table name="restaurants"></table>
So console.log prints each item... but I want to add each item to the table named restaurants in the ejs file. For now I'd simply like to add the whole string to the table- so one entry for each item as I iterate. I can figure out dissecting the JSON later.
I'm not sure how I can place this function in the ejs file perhaps and call it upon loading, or if that will even work the same way? Any help would be greatly appreciated!
maybe, var x = [{no:1, title:'hh', date:'2018-11-2' ..}, {..etc}]. right?
after get data,
in case jquery,
$("#restaurants").append(`<tr>
<td>no</td>
<td>title</td>
<td>date</td>
</tr>`)
for(let i = 0; i<x.length; i++){
$("#restaurants").append(`<tr>
<td>${i}</td>
<td>${x.title}</td>
<td>${x.date}</td>
</tr>`)
}
if you use vanila javascript, point is same.
you should control document.dom after get data.
Without knowing the form you get data in:
let restoTable = document.getElementById('restaurants');
var get_restaurants = function(route_callbck){
var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var async = require('async');
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "restaurants"
};
docClient.scan(params).eachPage((err, data, done) => {
if (data != null) {
for(var index=0; index<data.Items.length; index++) {
var record = data.Items[index];
var newRow = restoTable.insertRow(index); //insert new row to the end of a table
var dataArr = Object.values(record); //convert record to an array, if needed. Perhaps you already have...
for(var c=0; c<dataArr.length;c++){
var newCell = newRow.insertCell(c); //insert new cell to the end of the row...
var newText = document.createTextNode(dataArr[c]); //...and fill it
newCell.appendChild(newText);
}
}
}
});
};

Google Places API query 'opennow=true' returns 0 results (Node.js)

I am querying the Google Places API with the following set-up:
Backend: Radar Search Request via post-route (using Express and 'request'-module in Node.js)
Frontend: Display results on map, querying Place Detail request after clicking on marker icon (example from API documentation as reference)
All works fine, except that my search request doesn't seem to pass on my restriction of 'only places currently open' via 'opennow=true' within search request. There are surely restaurants open in Amsterdam at the time I send this request, I manually checked it on GoogleMaps. I've been trying all different ways of spelling and searched for similar solutions, but can't find the problem. Any help very much appreciated, thank you.
Code for reference:
app.post('/results', function(req,res){
//PARAMETERS FOR SEARCH QUERY FOR RESTAURANTS, OPEN NOW
const baseurl = 'https://maps.googleapis.com/maps/api/place/radarsearch/json?';
const location = 'location=52.370216,4.895168';
const radius = 'radius=5000';
const type = 'type=food';
const key = 'key='+process.env.googleapikey;
// const opennow = 'openNow=true'; //doesn't narrow down results, doesn't seem to get applied
// const opennow2 = 'open_now=true'; //doesn't narrow down results, doesn't seem to get applied
const opennow3 = 'opennow=true'; //0 search results returned, doesn't seem to work
const queryurl = `${baseurl}${location}&${radius}&${type}&${key}&${opennow3}`;
//SEARCH QUERY TO GOOGLE PLACES API, USING REQUEST MODULE
request({
uri: queryurl,
method: "GET",
timeout: 10000,
followRedirect: true,
maxRedireccts: 10
}, function(err, response, body) {
var allresults = [];
if(err){
console.log(err);
} else {
var responseparsed = JSON.parse(body);
var results = responseparsed.results;
for (var i = 0; i < results.length; i++) {
allresults.push(results[i]);
}
console.log('Maps found >'+results.length+'< results');
}
res.render("results", {allresults: allresults, mapsjsapikey: mapsjsapikey});
}
)
});

Issue when doing web scraper

I am scraping the webpage https://www.g2a.com/rising-storm-2-vietnam-steam-cd-key-global.html
I need to get the title from the table data.
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res) {
url = 'https://www.g2a.com/rising-storm-2-vietnam-steam-cd-key-global.html';
request(url, function(error, response, body) {
if (!error) {
var $ = cheerio.load(body);
var arr = [];
var title = $('.mp-user-rating tr').each(function() {
var tableData = $('.marketplace-name > .mp-rating-popup');
arr.push({ 'title': tableData.text() });
});
}
res.send('Check your console!')
});
})
app.listen('8081');
console.log('Magic happens on port 8081');
exports = module.exports = app;
Here the data is in third column and cannot able to get .mp-user-rating tr data what is expected.
The image shows the structure of the table
Any help would be appreciated.
So, I went to the page and ran this in the console.
var arr = [];
var title = jQuery('.mp-user-rating tr').each(function(i, element) {
var tableData = jQuery(element).find('.mp-rating-popup');
arr.push({ 'title': tableData.text() });
});
console.log(arr);
The array consists of 8 objects that each have the titles within them.
UPDATE:
I pulled in the html information using your code. I think the issue is, the html is loaded asynchronously by the website, as a result, pulling the html will only retrieve the static markup. You will need to use PhantomJS or chrome's headless browser in order to load the website and allow the asyncronous information to load, then you can grab the html.
See here for some good docs on PhantomJS: https://github.com/Medium/phantomjs

Categories

Resources