How to import pg-promise using ES6 syntax? - javascript

I am trying to set up a Postgres database in a nodejs server using ES6 syntax, but I don't think I'm importing and initializing pg-promise properly. If I were using common js sytax I would do the below:
// Create Database Connection
const pgp = require('pg-promise')({});
const db = pgp(config.db);
// Test connection
db.connect()
.then((obj) => {
console.log('Connected to database');
obj.done(); // success, release connection;
})
.catch((error) => {
console.error('ERROR:', error.message);
});
Using ES6 I am trying to do the below but the connection just hangs and doesn't complete or error out.
import pgPromise from 'pg-promise';
// Create Database Connection
const pgp = pgPromise({});
const db = pgp(config.db);
// Test connection
db.connect()
.then((obj) => {
console.log('Connected to database');
obj.done(); // success, release connection;
})
.catch((error) => {
console.error('ERROR:', error.message);
});
I've searched through the pg-promise docs and can't find anything about using it with ES6 syntax. Any ideas on what I should change?

The correct as I can see in the documentation.
Loading and initializing the library with Initialization Options:
const initOptions = {/* initialization options */};
const pgp = require('pg-promise')(initOptions);
or without Initialization Options:
const pgp = require('pg-promise')();
Create your Database object from the connection as pgp(connection, [dc]):
const db = pgp(connection);
For ES6 or TypeScript syntax
import pgPromise from 'pg-promise';
const pgp = pgPromise({/* Initialization Options */});
const db = pgp('postgres://username:password#host:port/database');

Is there any error message? Nodejs needs specific conditions to support es module, first make sure you have introduced the module correctly.
// index.mjs
import pgPromise from 'pg-promise';
const pgp = pgPromise({});
console.log(pgp);
Then execute with a --experimental-modules
node --experimental-modules index.mjs
More details https://blog.logrocket.com/es-modules-in-node-js-12-from-experimental-to-release/

Alright this is pretty stupid, but I found out my problem was just that I needed to update the pg-promise dependency. I was using version 8.5.1 and upgrading to 10.5.7 fixed this issue. For anyone else running into this issue you can use the code for ES6 as written in the question just make sure your pg-promise dependency is at the latest version.

Related

How can I fix TypeError: Cannot read properties of undefined (reading 'split') in mongoose?

I just connected mongoDB using mongoose.
But I got error TypeError: Cannot read properties of undefined (reading 'split')
How can I fix this error?
Here's my code
export const dbConnect = async () => {
mongoose.connect(process.env.NEXT_PUBLIC_MONGO_URI);
const db = mongoose.connection;
db.on('error', function () {
console.log('db connection failed!');
});
db.once('open', function () {
console.log('db connected!');
});
};
And I am using mongoose version 6.5.3, next version 12.2.5
If the error appears in the browser, it means that you are trying to use Mongoose in your client side code.
In fact, somewhere in its code, Mongoose checks for the version of the node installation it's using.
Being ran in the browser, there is no such thing as process.versions.node, hence the error.
What is value of process.env.NEXT_PUBLIC_MONGO_URI
Format should be like
mongoose.connect('mongodb://localhost/myapp');
mongoose.connect('mongodb://username:password#host:port/database?options...');
I think the problem will be in the connect function. The URI you give in might be wrong. Try logging it our before the function, to make sure it's a correct uri.
https://www.mongodb.com/docs/manual/reference/connection-string/
Here you can find the correct connection string format.
TL;DR
Use a dynamic import. instead of:
import mongoose from 'mongoose';
export const connectDb = async () => {
try {
await mongoose.connect('your-connection-string', { });
} catch (error) {
// exit process with failure
process.exit(1);
}
};
Try:
import dynamic from 'next/dynamic';
// import mongoose from 'mongoose';
export const connectDb = async () => {
try {
// Dynamically load mongoose
const mongoose = (await import('mongoose')).default;
await mongoose.connect('your-connection-string', { });
} catch (error) {
// exit process with failure
process.exit(1);
}
};
See the docs here: Dynamic Imports
Why does this work?
Luca was correct to say the following:
If the error appears in the browser, it means that you are trying to
use Mongoose in your client side code.
In fact, somewhere in its code, Mongoose checks for the version of the
node installation it's using.
To expand on that, node.js is not available on the client side of a next.js project, but it is available where server-side code runs such as getServerSideProps or /pages/api. I assume you only want to use this function inside the /pages/api folder and in that case it should work just fine.

Can't get .env variables to work in React using Contentful

I am trying to connect to Contentful's API in my react project. If I hardcode the space and access tokens it works fine, but if I try to use a .env file it's not getting the token.
Here's my code:
import {createClient} from "contentful";
export const client = () => {
//console.log(process.env)
let whatever = createClient({
space: process.env.REACT_APP_SPACE_ID ,
accessToken: process.env.REACT_APP_ACCESS_TOKEN,
});
return whatever;
};
export const getRecipes = async () => {
try{
const entries = await client().getEntries({
content_type: "recipe",
select: "fields"
});
return entries;
} catch(error){
console.log(`error fetch: ${error}`);
return;
}
}
I've tried various patches but nothing has worked. I have react-scripts installed as well.
I console logged the process.env and it doesn't have the token or space id.
I tried importing dotenv but that created some weird polyfill error that I've never seen before.
It could be that: your env file is not in the project folder but instead in the src/ folder...just check it once to make sure, it's a very easy mistake that a lot of people make.
Or if you have the client folder inside the server folder which is sometimes needed for deployment it might not be working because of that folder structure as well

how to mock node-redis using jest

i am using jest and trying to mock node-redis using redis-mock.
// redis.js
const redis = require("redis");
const client = redis.createClient({ host: '127.0.0.1', port: 6379 });
// redis.test.js
const redisMock = require("redis-mock");
describe("redis", () => {
jest.doMock("redis", () => jest.fn(() => redisMock));
const redis = require("./redis");
});
when i run the tests, i get an error
TypeError: redis.createClient is not a function
feels to me that i am doing something wrong when using jest.doMock().
would appreciate your assistance.
The following works for me:
import redis from 'redis-mock'
jest.mock('redis', () => redis)
I do not include the redis library in the test at all, but I include it only in the file which contains the tested class. (The file with tested class is, of course, included in the test file.)
If you are using jest, the switching of the mock and the actual implementation is possible automatically. Works great for CI.
jest.config.js
module.exports = {
// other properties...
setupFilesAfterEnv: ['./jest.setup.redis-mock.js'],
};
jest.setup.redis-mock.js
jest.mock('redis', () => jest.requireActual('redis-mock'));

"fetch is not found globally and no fetcher passed" when using spacejam in meteor

I'm writing unit tests to check my api. Before I merged my git test branch with my dev branch everything was fine, but then I started to get this error:
App running at: http://localhost:4096/
spacejam: meteor is ready
spacejam: spawning phantomjs
phantomjs: Running tests at http://localhost:4096/local using test-in-console
phantomjs: Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/unfetch.
For example:
import fetch from 'unfetch';
import { createHttpLink } from 'apollo-link-http';
const link = createHttpLink({ uri: '/graphql', fetch: fetch });
Here's a part of my api.test.js file:
describe('GraphQL API for users', () => {
before(() => {
StubCollections.add([Meteor.users]);
StubCollections.stub();
});
after(() => {
StubCollections.restore();
});
it('should do the work', () => {
const x = 'hello';
expect(x).to.be.a('string');
});
});
The funniest thing is that I don't even have graphql in my tests (although, I use it in my meteor package)
Unfortunately, I didn't to find enough information (apart from apollo-link-http docs that has examples, but still puzzles me). I did try to use that example, but it didn't help and I still get the same error
I got the same error importing a npm module doing graphql queries into my React application. The app was compiling but tests were failing since window.fetch is not available in the Node.js runtime.
I solved the problem by installing node-fetch https://www.npmjs.com/package/node-fetch and adding the following declarations to jest.config.js:
const fetch = require('node-fetch')
global.fetch = fetch
global.window = global
global.Headers = fetch.Headers
global.Request = fetch.Request
global.Response = fetch.Response
global.location = { hostname: '' }
Doing so we instruct Jest on how to handle window.fetch when it executes frontend code in the Node.js runtime.
If you're using nodejs do the following:
Install node-fetch
npm install --save node-fetch
Add the line below to index.js:
global.fetch = require('node-fetch');
The problem is this: fetch is defined when you are in the browser, and is available as fetch, or even window.fetch
In the server it is not defined, and either needs to be imported explicity, or a polyfill like https://www.npmjs.com/package/unfetch (as suggested in the error message) needs to be imported by your test code to make the problem go away.

TypeError: util.promisify is not a function?

I'm trying to promisify zlib.gunzip in my react application:
const zlib = require('zlib')
const util = require('util')
const gunzipPromisified = util.promisify(zlib.gunzip)
But I get this error:
TypeError: util.promisify is not a function
That works fine if I put it in a standalone script file and run it through node.
If I try:
import zlib from 'zlib'
import util from 'util'
const gunzipPromisified = util.promisify(zlib.gunzip)
I get something even fancier:
TypeError: __WEBPACK_IMPORTED_MODULE_8_util___default.a.promisify is not a function
What am I missing?
[Edit] The node.js version installed on my laptop is 8.9.1.
[Edit] As somebody commented, the node.js installed in my local development environment has nothing to do with what the app code has access to in the browser. So now my question is, how do I determine what API I have access to in the browser?
I had the same problem in Ionic. The util promisify didn't work for me either, and generated the same error as the one for OP. I ended up using this simple solution copied below:
const promisify = (fn) => {
return (...args) => {
return new Promise((resolve, reject)=>{
fn(...args, function(err, res){
if(err){
return reject(err);
}
return resolve(res);
})
})
}
}
And then:
const requestPromisified = promisify(request)
I had the same problem, it got fixed by updating Node to a version higher than Node 7.
n latest
In my case Node 9.2.0 as this was added later.
Of course everything works fine when I switch to bluebird's Promise.

Categories