Mongo collection is accessible via mongosh (mongo shell) but not nodejs script - javascript

Running the mongod process in the background, in the mongo shell (mongosh), I have the wikipedia database loaded in my database "enwiki". So in the shell, I can just type db.pages.find(), and it will show me some pages from Wikipedia. Similarly, if I call db.getCollectionNames(), it returns ['pages']. db.getCollection("pages").find() also works.
However, if I go to my nodejs script, db.collection("pages").find() has nothing in it.
const MongoClient = require("mongodb").MongoClient;
const url = 'mongodb://localhost:27017/';
const dbName = 'enwiki';
const client = new MongoClient(url, { useUnifiedTopology: true });
client.connect().then(client => {
console.log('Connected successfully to server');
const db = client.db(dbName);
const cursor = db.collection("pages").find();
cursor.forEach(doc => { console.log(doc.plaintext);});
});
Running the above code just prints 'Connected successfully to server' and stops. (It should also print the plaintext of all my Wikipedia articles in my database.)
I'm new to mongo, so I feel like I'm missing something obvious. The database was originally created using dumpster-dive. Calling db.listCollections() returns this in the node debugger:
{ _events: Object,
_eventsCount: 0,
_maxListeners: 'undefined',
parent: Db,
filter: Object,
... }
That object does not contain the pages collection that I am expecting. How do I access the pages collection?
EDIT 1/18/22 (next day): Ran it today not in the debugger and it just worked. For some reason, running db.collection("pages").find() and db.collection("pages").find().limit(1) in the node debugger returns a similarly weird object to the one above. On the other hand, running cursor.forEach(doc => { console.log(doc.plaintext);}); in the node debugger just returns:
{ [[PromiseState]]: 'pending',
[[PromiseResult]]: 'undefined' }
And ends without doing anything else, so I thought it was doing nothing. In my not fully reduced code shown here, I also had a couple of typos within the forEach promise whose errors were getting suppressed.

The above code does work and it just didn't seem like it did. In my case, I think it was a combination of error suppression that I wasn't seeing and this weird node debugger behaviour that led me to believe it wasn't working. I would love an explanation for why this debugger behaviour is happening and how to avoid/fix it though.

Related

load user.mail from Auth0 with async function

i want load the user.mail from Auth0 and safe there at a const. but I get a arrow. i don't see the error. can somebody help me to find the solution?
const userMailInfo = async () => {
auth0Client = await auth.createClient();
const result = await auth0Client.getUser().then(user => {
console.log('mail', user.email);
user.mail;
});
return result;
}
;(async () => {
const users = await userMailInfo()
console.log(users)
})()
i get follow error:
(node:19676) UnhandledPromiseRejectionWarning: ReferenceError: document is not defined
It looks like these errors are caused by code running on the server-side, where they do not have access to 'document' and the like. In SvelteKit, endpoints always run on the server, and therefore do not have access to all the elements in the 'Client API'.
To guard code from running on the server side, try calling it through OnMount(). I've linked a Sapper issue outlining some similar solutions, e.g., using if(process.browser). I am not sure if this works in SvelteKit, but may be worth checking out.
Note: It seems like the error occured outside of the provided code snippet.
SvelteKit Discord Server contains some discussions on the topic, try searching for 'UnhandledPromiseRejectionWarning ReferenceError'.
(for Sapper) https://github.com/sveltejs/sapper/issues/1226

Is it possible to link a random html site with node javascript?

Is it possible to link a random site with node.js, when I say that, Is it possible to link it with only a URL, if not then I'm guessing it's having the file.html inside the javascript directory. I really wanna know if it's possible because the html is not mine and I can't add the line of code to link it with js that goes something like (not 100% sure) <src = file.html>
I tried doing document = require('./page.html'); and ('./page') but it didn't work and when I removed the .html at the end of require it would say module not found
My keypoint is that the site shows player count on some servers, and I wanna get that number by linking it with js and then using it in some code which I have the code to (tested in inspect element console) but I don't know how to link it properly to JS.
If you wanna take a look at the site here it is: https://portal.srbultras.info/#servers
If you have any ideas how to link a stranger's html with js, i'd really appreciate to hear it!
You cannot require HTML files unless you use something like Webpack with html-loader, but even in this case you can only require local files. What you can do, however, is to send an HTTP Request to the website. This way you get the same HTML your browser receives whenever you open a webpage. After that you will have to parse the HTML in order to get the data you need. The jsdom package can be used for both steps:
const { JSDOM } = require('jsdom');
JSDOM.fromURL('https://portal.srbultras.info/')
.then(({ window: { document }}) => {
const servers = Array.from(
document.querySelectorAll('#servers tbody>tr')
).map(({ children }) => {
const name = children[3].textContent;
const [ip, port] = children[4]
.firstElementChild
.textContent
.split(':');
const [playersnum, maxplayers] = children[5]
.lastChild
.textContent
.split('/')
.map(n => Number.parseInt(n));
return { name, ip, port, playersnum, maxplayers };
});
console.log(servers);
/* Your code here */
});
However, grabbing the server information from a random website is not really what you want to do, because there is a way to get it directly from the servers. Counter Strike 1.6 servers seem to use the GoldSrc / Source Server Protocol that lets us retrieve information about the servers. You can read more about the protocol here, but we are just going to use the source-server-query package to send queries:
const query = require('source-server-query');
const servers = [
{ ip: '51.195.60.135', port: 27015 },
{ ip: '51.195.60.135', port: 27017 },
{ ip: '185.119.89.86', port: 27021 },
{ ip: '178.32.137.193', port: 27500 },
{ ip: '51.195.60.135', port: 27018 },
{ ip: '51.195.60.135', port: 27016 }
];
const timeout = 5000;
Promise.all(servers.map(server => {
return query
.info(server.ip, server.port, timeout)
.then(info => Object.assign(server, info))
.catch(console.error);
})).then(() => {
query.destroy();
console.log(servers);
/* Your code here */
});
Update
servers is just a normal JavaScript array consisting of objects that describe servers, and you can see its structure when it is logged into the console after the information has been received, so it should not be hard to work with. For example, you can access the playersnum property of the third server in the list by writing servers[2].playersnum. Or you can loop through all the servers and do something with each of them by using functions like map and forEach, or just a normal for loop.
But note that in order to use the data you get from the servers, you have to put your code in the callback function passed to the then method of Promise.all(...), i.e. where console.log(servers) is located. This has to do with the fact that it takes some time to get the responses from the servers, and for that reason server queries are normally asynchronous, meaning that the script continues execution even though it has not received the responses yet. So if you try to access the information in the global scope instead of the callback function, it is not going to be there just yet. You should read about JavaScript Promises if you want to understand how this works.
Another thing you may want to do is to filter out the servers that did not respond to the query. This can happen if a server is offline, for example. In the solution I have provided, such servers are still in the servers array, but they only have the ip and port properties they had originally. You could use filter in order to get rid of them. Do you see how? Tell me if you still need help.

How can data schema be rejected before the mongodb connection is made by node.js and mongoose?

I don't understand a specific asynchronous javascript code: I have a very simple few lines of javascript running by node.js where I query a local mongoDB, on the main lines it does this:
require mongoose
a promise to connect to the db
mongoose.connect("...url to my local mongoDB...")
.then(console.log("Connected to DB..."))
create a schema
create a model from schema
define an async function to create a new object, save it as document in mongoDB and console.log the result returned after the attempt to save the document.
What I don't understand is the order of the console.log("Connect to DB") and console.log(result from document.save()): indeed, when there are no error on saving, the order seems ok: i have first the "Connected to DB..." then the returned saved document:
But when there is a data validation error for not respecting some requirements, then the "Connected to DB" is printed after the "Connected to DB":
Regarding the structure of the code, I don't understand why the "Connected to the DB..." is printed after the print of the Error. I suspect ansynchronous code to be the reason but i don't understand why. This very simple few lines of code come from the "Programming with Mosh" course where we can see the exact same behavior on his console.
A little bit more code details:
const mongoose = require("mongoose")
mongoose
.connect(my_mongo_db_url)
.then(() => console.log("Connected to DB"))
.catch(err => console.log("Could not connect to DB"))
const courseSchema = new mongoose.Schema({ ...course schema... })
const Course= mongoose.model("Course", courseSchema )
async function createCourse(){
const course = new Course({ ...new course values... })
try { const result = await course.save()}
catch (err) { console.log(err.message)}
}
createCourse()
I copy here the #jonrsharpe comment that answered my question:
"The call to course.save may be executed before the connection is made, but its internal implementation waits for the connection: https://mongoosejs.com/docs/connections.html#buffering"

Is it safe to use a single Mongoose database from two files/processes?

I've been working on a server and a push notification daemon that will both run simultaneously and interact with the same database. The idea behind this is that if one goes down, the other will still function.
I normally use Swift but for this project I'm writing it in Node, using Mongoose as my database. I've created a helper class that I import in both my server.js file and my notifier.js file.
const Mongoose = require('mongoose');
const Device = require('./device'); // This is a Schema
var uri = 'mongodb://localhost/devices';
function Database() {
Mongoose.connect(uri, { useMongoClient: true }, function(err) {
console.log('connected: ' + err);
});
}
Database.prototype.findDevice = function(params, callback) {
Device.findOne(params, function(err, device) {
// etc...
});
};
module.exports = Database;
Then separately from both server.js and notifier.js I create objects and query the database:
const Database = require('./db');
const db = new Database();
db.findDevice(params, function(err, device) {
// Simplified, but I edit and save things back to the database via db
device.token = 'blah';
device.save();
});
Is this safe to do? When working with Swift (and Objective-C) I'm always concerned about making things thread safe. Is this a concern? Should I be worried about race conditions and modifying the same files at the same time?
Also, bonus question: How does Mongoose share a connection between files (or processes?). For example Mongoose.connection.readyState returns the same thing from different files.
The short answer is "safe enough."
The long answer has to do with understanding what sort of consistency guarantees your system needs, how you've configured MongoDB, and whether there's any sharding or replication going on.
For the latter, you'll want to read about atomicity and consistency and perhaps also peek at write concern.
A good way to answer these questions, even when you think you've figured it out, is to test scenarios: Hammer a duplicate of your system with fake data and events and see if what happen is OK or not.

Error: Network error: Error writing result to store for query (Apollo Client)

I am using Apollo Client to make an application to query my server using Graphql. I have a python server on which I execute my graphql queries which fetches data from the database and then returns it back to the client.
I have created a custom NetworkInterface for the client that helps me to make make customized server request (by default ApolloClient makes a POST call to the URL we specify). The network interface only has to have a query() method wherein we return the promise for the result of form Promise<ExecutionResult>.
I am able to make the server call and fetch the requested data but still getting the following error.
Error: Network error: Error writing result to store for query
{
query something{
row{
data
}
}
}
Cannot read property 'row' of undefined
at new ApolloError (ApolloError.js:32)
at ObservableQuery.currentResult (ObservableQuery.js:76)
at GraphQL.dataForChild (react-apollo.browser.umd.js:410)
at GraphQL.render (react-apollo.browser.umd.js:448)
at ReactCompositeComponent.js:796
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:746)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:724)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:645)
at ReactCompositeComponentWrapper.performUpdateIfNecessary (ReactCompositeComponent.js:561)
at Object.performUpdateIfNecessary (ReactReconciler.js:157)
at runBatchedUpdates (ReactUpdates.js:150)
at ReactReconcileTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
at Object.flushBatchedUpdates (ReactUpdates.js:172)
at ReactDefaultBatchingStrategyTransaction.closeAll (Transaction.js:206)
at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:153)
at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
at Object.enqueueUpdate (ReactUpdates.js:200)
I want to know the possible cause of the error and solution if possible.
I had a similar error.
I worked it out by adding id to query.
for example, my current query was
query {
service:me {
productServices {
id
title
}
}
}
my new query was
query {
service:me {
id // <-------
productServices {
id
title
}
}
}
we need to include id,
otherwise it will cause the mentioned error.
{
query something {
id
row {
id
data
}
}
}
I've finally found out what is causing this issue after battling with it in various parts of our app for months. What helped to shed some light on it was switching from apollo-cache-inmemory to apollo-cache-hermes.
I experimented with Hermes hoping to mitigate this ussue, but unfortunately it fails to update the cache the same as apollo-cache-inmemory. What is curious though is that hermes shows a very nice user friendly message, unlike apollo-cache-inmemory. This lead me to a revelation that cache really hits this problem when it's trying to store an object type that is already in the cache with an ID, but the new object type is lacking it. So apollo-cache-inmemory should work fine if you are meticulously consistent when querying your fields. If you omit id field everywhere for a certain object type it will happily work. If you use id field everywhere it will work correctly. Once you mix queries with and without id that's when cache blows up with this horrible error message.
This is not a bug-it's working as intended, it's even documented here: https://www.apollographql.com/docs/react/caching/cache-configuration/#default-identifiers
2020 update: Apollo has since removed this "feature" from the cache, so this error should not be thrown anymore in apollo-client 3 and newer.
I had a similar looking issue.
Perhaps your app was attempting to write (the network response data) to the store with the wrong store address?
Solution for my problem
I was updating the store after adding a player to a team:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id } };
const data = store.readQuery(addr);
stored.teams.players.push(response.data.player));
store.writeQuery({...addr, data});
}
I started to get a similar error above (I'm on Apollo 2.0.2)
After digging into the store, I realised my QUERY_TEAM request made with one variable meta defaulting to null. The store "address" seems to use the *stringified addr to identify the record. So I changed my above code to mimic include the null:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id, meta: null } };
const data = store.readQuery(addr);
data.teams.players.push(response.data.player));
store.writeQuery({...addr, data});
}
And this fixed my issue.
* Defaulting to undefined instead of null will probably avoid this nasty bug (unverified)
Further info
My issue may be only tangentially related, so if that doesn't help I have two peices of advice:
First, add these 3 lines to node_modules/apollo-cache-inmemory/lib/writeToStore.js to alert you when the "record" is empty.
And then investigate _a to understand what is going wrong.
exports.writeResultToStore = writeResultToStore;
function writeSelectionSetToStore(_a) {
var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context;
var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap;
+if (typeof result === 'undefined') {
+ debugger;
+}
Second, ensure all queries, mutations and manual store updates are saving with the variables you expect
For me adding "__typename" into query helped.
Solution for this is 1. it happening when missing id, second one is it is happening when you have same query and hitting them alternately.
Example if you have query like dog and cat.
query dog(){id, name}
query cat(){id, name }
here both query are same just their header are different, during that time, this type of issue is coming. currently i have fetching same query with different status and getting this error and am lost in search of solution.

Categories