I'm having a play with the MEAN stack in order to teach myself a bit of javascript, and use Angular, and i'm having trouble setting up a MEAN environment.
I'm trying to connect to my Mongodb database, and read the contents of the "users" collection, which should contain two records, "John Doe", and "Jane Doe".
This is what my connection string looks like, as well as the constants I have at the top of the api.js
//Importing express, Router, Mongoclient and ObjectID
const express = require('express');
const router = express.Router();
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
//Connect
const connection = (closure) => {
//Connecting to "mongod://localhost" line, "/mean" is the name of the DB you
//want to connect too
return MongoClient.connect('mongodb://localhost:27017/mean', { useNewUrlParser: true }, (err, client) => {
if (err) return console.log(err);
var db = client.db('mean');
db.collection('users').findOne({}, function (findErr, result) {
if (findErr) throw findErr;
console.log(result.name);
client.close()
});
//closure(db);
});
};
When I run "node server" from the command line, it runs ok with no error:
C:\Users\jack_\OneDrive\Documents\code\mean>node server
Running on localhost:3000
However, when I try and navigate to "localhost:3000/api/users", nothing happens, the page gets stuck loading, and if I go back to the command line, it shows the first entry in "users":
C:\Users\jack_\OneDrive\Documents\code\mean>node server
Running on localhost:3000
John Doe
I can open the "localhost:3000/api" with no problem, and it takes me to the AngularJS landing page just fine.
I've had a read of over stackoverflow questions and found that there may be a problem with the mongodb driver, as they accidently released a beta version onto npm, so i checked my database version and the driver version:
C:\Users\jack_\OneDrive\Documents\code\mean>"C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe" --version
db version v4.0.2
git version: fc1573ba18aee42f97a3bb13b67af7d837826b47
allocator: tcmalloc
modules: none
build environment:
distmod: 2008plus-ssl
distarch: x86_64
target_arch: x86_64
Database version:
C:\Users\jack_\OneDrive\Documents\code\mean>"C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe" --version
MongoDB shell version v4.0.2
git version: fc1573ba18aee42f97a3bb13b67af7d837826b47
allocator: tcmalloc
modules: none
build environment:
distmod: 2008plus-ssl
distarch: x86_64
target_arch: x86_64
Looking at the other stackoverflow answers, because of the version I'm using, MongoClient.connect now returns a client object containing the database object
So I ammended the code with:
MongoClient.connect('mongodb://localhost:27017/mean', { useNewUrlParser: true }
and
var db = client.db('mean');
db.collection('users').findOne({}, function (findErr, result) {
if (findErr) throw findErr;
console.log(result.name);
client.close()
This got rid of my original error, which was "db.collections is not a function", but, according to the tutorial I'm following, I should see the contents of the "users" collection in a web browser, along with some other information, kinda like this:
{"status":200,"data":[{"_id":"598ce66bf7d6d70def3d9f6f","name":"John Doe"}
But, I'm not,
So what have I done wrong? or am I missing something, bearing in mind I was writing this at 3AM, so I more than likely missed something
Thanks in Advance
You can use below code to connect with db and find the data
const express = require('express');
const router = express.Router();
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mean";
MongoClient.connect(url, function(err, client) {
if (err) throw err;
var db = client.db("mean");
db.collection("users").findOne({}, function(err, result) {
if (err) throw err;
console.log(result.name);
db.close();
});
});
Related
So I've got a new Cypress 10 project, and I'm trying to integrate some functionality to allow me to make some basic database calls to our Oracle database (which is on a server I have direct access to, not running locally).
I've been following this guide which shows how to add the oracledb package as a Cypress plugin, but the method used (using the /plugin directory) has been depreciated in Cypress 10 so I can't follow the example exactly.
I've instead tried applying this logic using the Cypress plugin documentation as a guide and I think I have something that almost works, but I can't seem to connect to any database, even if the location is in my tnsnames.ora file (although I'm providing the connection string directly for this particular project).
Here's what my cypress.config.ts file looks like, with the code I've created (I'm using Cucumber in my implementation too, thus why those references are present here):
import { defineConfig } from "cypress";
import createBundler from "#bahmutov/cypress-esbuild-preprocessor";
import { addCucumberPreprocessorPlugin } from "#badeball/cypress-cucumber-preprocessor";
import createEsbuildPlugin from "#badeball/cypress-cucumber-preprocessor/esbuild";
const oracledb = require("oracledb");
oracledb.initOracleClient({ libDir: "C:\\Users\\davethepunkyone\\instantclient_21_6" });
// This data is correct, I've obscured it for obvious reasons
const db_config = {
"user": "<username>",
"password": "<password>",
"connectString": "jdbc:oracle:thin:#<hostname>:<port>:<sid>"
}
const queryData = async(query, dbconfig) => {
let conn;
try{
// It's failing on this getConnection line
conn = await oracledb.getConnection(dbconfig);
console.log("NOTE===>connect established")
return await conn.execute(query);
}catch(err){
console.log("Error===>"+err)
return err
} finally{
if(conn){
try{
conn.close();
}catch(err){
console.log("Error===>"+err)
}
}
}
}
async function setupNodeEvents(
on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions ): Promise<Cypress.PluginConfigOptions> {
await addCucumberPreprocessorPlugin(on, config);
on("file:preprocessor", createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
on("task", {
sqlQuery: (query) => {
return queryData(query, db_config);
},
});
return config;
}
export default defineConfig({
e2e: {
specPattern: "**/*.feature",
supportFile: false,
setupNodeEvents,
},
});
I've then got some Cucumber code to run a test query:
Then("I do a test database call", () => {
// Again this is an example query for obvious reasons
const query = "SELECT id FROM table_name FETCH NEXT 1 ROWS ONLY"
cy.task("sqlQuery", query).then((resolvedValue: any) => {
resolvedValue["rows"].forEach((item: any) => {
console.log("result==>" + item);
});
})
})
And here are the dependencies from my package.json:
"dependencies": {
"#badeball/cypress-cucumber-preprocessor": "^12.0.0",
"#bahmutov/cypress-esbuild-preprocessor": "^2.1.3",
"cypress": "^10.4.0",
"oracledb": "^5.4.0",
"typescript": "^4.7.4"
},
I feel like I'm somewhat on the right track as when I run the feature step above, the error I get back is:
Error===>Error: ORA-12154: TNS:could not resolve the connect identifier specified
This makes me think that it has at least called the node-oracledb package to generate the error but I can't really tell if I've made an obvious error or not (I'm pretty new to JS/TS). I know I've referenced the right path for the oracle instant client and it's been initialized correctly at least because Cypress points out a config error if the path is incorrect. I know the database paths work as well because we have an older Selenium implementation that can connect using the details I'm providing.
I think I'm just more curious to know if anyone has so far successfully implemented an oracledb connection with Cypress 10 or if someone who has a bit more Cypress experience can spot any obvious errors in my code as resources for this particular combination of packages seem to be non-existent (possibly because Cypress 10 is reasonably new).
NOTE: I am planning on switching to using environmental variables for the database connection information that will eventually be passed into the project - I just want to get a connection working first before I tackle that issue.
Oracle's C stack drivers like node-oracledb are not using Java so the JDBC connection string needs changing from:
"connectString": "jdbc:oracle:thin:#<hostname>:<port>:<sid>"
If you were using:
jdbc:oracle:thin:#mydbmachine.example.com:1521/orclpdb1
then your Node.js code should use:
connectString : "mydbmachine.example.com:1521/orclpdb1"
Since you're using the very obsolete SID syntax, check the node-oracledb manual for the solution if you can't use a service name: JDBC and Oracle SQL Developer Connection Strings.
I'm trying to write a simple rest API to connect to my sql Server database and execute a simple query to retrieve data from a database.
I'm following this tutorial: https://medium.com/voobans-tech-stories/how-to-quickly-create-a-simple-rest-api-for-sql-server-database-7ddb595f751a
Here's where my confusion lies:
The example has a server initialization file that looks like this:
var express = require('express'); // Web Framework
var app = express();
var sql = require('mssql'); // MS Sql Server client
// Connection string parameters.
var sqlConfig = {
user: 'UserName',
password: 'mot de passe',
server: 'localhost',
database: 'DatabaseName'
}
// Start server and listen on http://localhost:8081/
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("app listening at http://%s:%s", host, port)
});
It also has a select query the example uses on the customer table located in the database:
app.get('/customers', function (req, res) {
sql.connect(sqlConfig, function() {
var request = new sql.Request();
request.query('select * from Sales.Customer', function(err, recordset) {
if(err) console.log(err);
res.end(JSON.stringify(recordset)); // Result in JSON format
});
});
})
What I'm not understanding is how these two files are connected or interacting. At the end of the tutorial, the author says in order to test the example, copy the code into a file and run it. The example has 4 separate files though - am I putting them all into the same document?
yes you can put all code snippets in the same file for your test. It will be the easiest way since they all using the app variable.
But if you want a bigger application, it's cleaner in multiple files. You can then use code from another file using an import like require('./filename.js');
I am trying to run a Google Cloud Tasks task using a Cloud Function, but I'm hitting an error where any region I try to use is wrong.
The code is basic. All is well until it stops because of the following error:
Error: {"code":3,"message":"Location 'europe-west1' is not a valid location. Use ListLocations to list valid locations.","details":[]}
If I attempt to use, for example, us-central1, it will report:
Error: {"code":3,"message":"Location must equal europe-west1 because the App Engine app that is associated with this project is located in europe-west1","details":[]}
I am using the Google Cloud Tasks API with Node.js for creating a new Task:
const client = new CloudTasksClient({ fallback: true });
const parent = client.queuePath(PROJECT, 'europe-west1', QUEUE);
A full example can be found here: https://github.com/googleapis/nodejs-tasks/blob/master/samples/createHttpTaskWithToken.js
The URL called is:
""https://cloudtasks.googleapis.com:443/$rpc/google.cloud.tasks.v2beta3.CloudTasks/CreateTask"
If I run the locations list command, this is the output:
$ gcloud tasks locations list
europe-west1 projects/[project-id]/locations/europe-west1
Edit: Using the REST API (https://cloud.google.com/tasks/docs/reference/rest/v2beta3/projects.locations.queues.tasks/create) with the same configuration works. It may be a bug in the client?
I am really not sure what is wrong with my setup.
Not sure what information would be helpful to debug this, so apologies in advance if there's not enough information.
I realized which the example that you are using is for non App Engine/Cloud functions environments please try the simple example that is in the npm page.
Please check on your package.json that you are defining the latest version of google-cloud/tasks library, at this time it is 1.9.0
You don't need to use a Ouath token within App Engine/ Cloud Functions environments, because are already configured with a service account.
// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('#google-cloud/tasks');
// Instantiates a client.
const client = new CloudTasksClient();
// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-appengine-queue';
// const location = 'us-central1';
// const payload = 'hello';
// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
},
};
if (payload) {
task.appEngineHttpRequest.body = Buffer.from(payload).toString('base64');
}
if (inSeconds) {
task.scheduleTime = {
seconds: inSeconds + Date.now() / 1000,
};
}
const request = {
parent: parent,
task: task,
};
console.log('Sending task:');
console.log(task);
// Send create task request.
const [response] = await client.createTask(request);
const name = response.name;
console.log(`Created task ${name}`);
Here is my situation : I'm developing a Chatbot on Microsoft azure platform using Node.js. For the moment the bot messages are hard-coded in .json files.
I want to improve it by using calls to a database.
I have a SQLite database file working fine (I used a browser for SQLite and made my requests). But the problem is :
How do can I use my .db file from my project ? Is this possible to somehow "read" the database file from my dialogs and then make my request to get what I need from my database ?
I know that you can call a database with the chatbot, but the issue here is that I only have the file and nothing deployed to call.
Example of what the result should give :
"Hey chatbot, tell me about Mona Lisa"
This triggers the dialogs that will ask the database : "SELECT info FROM arts WHERE arts.title LIKE '%Mona Lisa%' ";
And send the result in session.send(results).
Thanks !
Note : I'm just an intern in my company, the database file is the only thing they gave me and I have to find a solution with it
I got the solution after some research :
First you need to install sqlite3 with npm for example, then use this at the beginning of your code :
var sqlite3 = require('sqlite3').verbose();
var path = require('path');
var db_path = path.resolve(__dirname, name_Of_Your_DB);
And then work on your file with the request you need :
var db = new sqlite3.Database(db_path, sqlite3.OPEN_READONLY,(err) => {
if (err) {
return console.error(err.message);
}
//console.log("Stuff that is processed only if no error happened.");
});
var req = "YOUR REQUEST";
db.get(req, [your_parameter],(err, row) => {
if (err) {
return console.error(err.message);
}
});
db.close((err) => {
if (err) {
return console.log(err.message);
}
});
The documentation about node.js and sqlite3 is quite complete :
http://www.sqlitetutorial.net/sqlite-nodejs/query/
I'm trying to make an angularjs app 12 factor compliant regarding config (http://12factor.net/config).
It should depend on the environment and I should not see the words development, test, production, etc. in the code.
Variables could be stored in bash env for example.
I could pass them to a webserver.
I already thought of an .erb template file to erb config.js.erb > config.js, but if I change a variable while the application is running I'd have to redo this.
I already found this article http://mindthecode.com/how-to-use-environment-variables-in-your-angular-application/
But it's a big lie and Grunt.js to do this, really... Anyway.
I know 12factor philosophy wasn't made for frontend application but my angular application could be deployed in many different servers across many environment and it won't harm anyone to try to do things properly :).
Thanks !
Edit:
The config parameters I'd like to use would be some stuff like :
app:
api:
url: "The url of the api server"
port: 8080
cdn:
images: "url of my images caching service"
google:
oauth:
"api_key": "The api key used for that deployment"
#other external frontend services
Other Edit:
This guy kinda went with an answer : http://bahmutov.calepin.co/inject-valid-constants-into-angular.html which I find kind of ugly and totally bound to angularjs; but it works !
Here is the solution I found, it's totally bound to angularjs but it works for me on Heroku and it's very simple. I just append my conf module to the generated code.
Everytime I restart the app a new version of the code is copied therefore the Append only happens once.
The Append just redefines an already existing configuration variable.
If someone find something more 'classy' I'd be happy to put it as the right solution !
var compression = require('compression');
var express = require('express');
var logfmt = require('logfmt');
var stdio = require('stdio');
var glob = require("glob");
var fs = require('fs');
// ------------------------
// Read config from args
var ops = stdio.getopt({
'url': {
key: 'u',
args: 1,
default: '',
description: 'Url of api server'
},
'port': {
key: 'p',
args: 1,
default: 5000,
description: 'Port on which to listen'
}
});
var port = ops.port || process.env.PORT;
ops.port = undefined;
// ------------------------
// Append config to js built file
var codeToAppend = 'angular.module("project.config",[]).constant("ApiConfig",' + JSON.stringify(ops) + ');';
glob(__dirname + '/dist/scripts/scripts.*.js', function(er, files) {
fs.appendFile(files[0], codeToAppend, function(err) {
if (err) {
throw err;
}
console.log('The "conf code" was appended to file!');
});
});
// ------------------------
// Start App :3
var app = express();
app.use(logfmt.requestLogger());
app.use(compression({
threshold: 512
}));
app.use(express.static(__dirname + '/dist'));
app.get('/config', function(req, res) {
res.json(ops);
});
app.listen(port);
I found a repository on github that hopefully help you Angular-Express-Train-Seed