Setting "params" for GET requests using RESTDataSource - javascript

Problem: I am trying to make a GET request using RESTDataSource's get method, but I'm receiving a ERR_INVALID_URL error.
My code:
async getMediaIDs() {
let response;
try {
response = await this.get(`${process.env.INSTA_ID}/media`, {
access_token: `${process.env.PAGE_ACCESS_TOKEN}`,
});
} catch(err) {
throw new Error(err);
}
return response.data.data;
}
Expected: The request is successful, with the full url being:
https://graph.facebook.com/{insta_id}/media?access_token={access_token}
Actual: I receive this error:
2019-11-15T10:03:42.974335+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: Error: TypeError [ERR_INVALID_URL]: Invalid URL: 17841402041188678/media
2019-11-15T10:03:42.974379+00:00 app[web.1]: at InstagramAPI.getMediaIDs (/app/src/data/instagram.js:17:13)
2019-11-15T10:03:42.974382+00:00 app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:93:5)
2019-11-15T10:03:42.974395+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
2019-11-15T10:03:42.974467+00:00 app[web.1]: (node:4) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I suspect that the error is in
this.get(`${process.env.INSTA_ID}/media`, {
access_token: `${process.env.PAGE_ACCESS_TOKEN}`,
});
because I am not setting the params parameter correctly (...I think. I don't know.)
While searching for a solution, I found the RESTDataSource file, which leads to this:
protected async get<TResult = any>(
path: string,
params?: URLSearchParamsInit, // <----- (What I'm trying to set)
init?: RequestInit,
): Promise<TResult> {
return this.fetch<TResult>(
Object.assign({ method: 'GET', path, params }, init),
);
}
Following URLSearchParamsInit leads to this:
export type URLSearchParamsInit =
| URLSearchParams
| string
| { [key: string]: Object | Object[] | undefined }
| Iterable<[string, Object]>
| Array<[string, Object]>;
I'm not too familiar with TypeScript, but I'm guessing that those are ways to define params?.
Anyways, my question is how do I set the params parameter for RESTDataSource's get method?
side note for the Apollo devs: An API page for RESTDataSource would be brilliant! I would be willing to help document it, as proper documentation currently isn't available.

Based on the error you're seeing, it doesn't look like you're setting a baseURL. Without the baseURL set, you end up with 17841402041188678/media as the complete URL, which is not a valid URL. You can set the baseURL inside your RESTDataSource's constructor:
class InstagramAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'https://graph.facebook.com/';
}
// ...
}

Related

Unhandled promise rejection using NestJS

When I execute the following code I get "201 Created" response from the server but actually data is not inserted in the server.
I am using nestJS with TypeORM and Postgres for my application.
import { Repository, EntityRepository } from "typeorm";
import { User } from './user.entity';
import { AuthCredentialsDto } from './dto/auth-credentials.dto';
import { ConflictException, InternalServerErrorException } from "#nestjs/common";
#EntityRepository(User)
export class UserRepository extends Repository<User>{
async signUp(authCredentialsDto: AuthCredentialsDto): Promise<void>{
const {username, password} = authCredentialsDto;
const user = new User();
user.username = username;
user.password = password;
try{
await user.save();
} catch (error) {
if (error.code === '23505'){ // error code for duplicate value in a col of the server
throw new ConflictException('Username already exists');
} else {
throw new InternalServerErrorException();
}
}
}
}
And I get following response in the VS Code terminal, instead of getting "201 Crated" from the server:
(node:14691) UnhandledPromiseRejectionWarning: Error: Username already exists
at UserRepository.signUp (/home/rajib/practicing coding/nestJS-projects/nestjs-task-management/dist/auth/user.repository.js:24:23)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:14691) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:14691) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
And the controller modules code is following:
import { Controller, Post, Body, ValidationPipe } from '#nestjs/common';
import { AuthService } from './auth.service';
import { AuthCredentialsDto } from './dto/auth-credentials.dto';
#Controller('auth')
export class AuthController {
constructor( private authService: AuthService){}
#Post('/signup')
signUp(#Body(ValidationPipe) authCredentialsDto: AuthCredentialsDto): Promise<void>{
return this.authService.signUp(authCredentialsDto);
}
}
Good day.
I think the issue you have here is not awaiting the method call to the authService.signup() method in your AuthController...
So, the correction should be:
In the AuthService::signup() method:
return this.userRepository.signup(authCredentialsDto);
In the AuthController::signup() method:
return this.authService.signup(authCredentialsDto);

Trouble to destroy a model with Sequelize

What is happening?
I am trying to destroy one model via params. But when I try to destroy, it appears this error at the console.
(node:13350) UnhandledPromiseRejectionWarning: TypeError: results.map is not a function
at Query.handleSelectQuery (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/abstract/query.js:261:24)
at Query.formatResults (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/mysql/query.js:118:19)
at /home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/mysql/query.js:71:29
at tryCatcher (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:729:18)
at _drainQueueStep (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:93:12)
at _drainQueue (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:86:9)
at Async._drainQueues (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:102:5)
at Immediate.Async.drainQueues [as _onImmediate] (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:15:14)
at processImmediate (internal/timers.js:439:21)
at process.topLevelDomainCallback (domain.js:130:23)
(node:13350) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13350) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
The route that call the function
router.delete('/agricultural/announce/:id', passport.authenticate(), (req, res) => {
AnnouncementAgricultural.destroy(req, res);
})
The function
exports.destroy = async (req, res) => {
if (!await authorize(req, res, true)) {
return res.status(400).json({ success: false, errors: "unauthorized" })
}
await sequelize.query('SET FOREIGN_KEY_CHECKS=0;', { type: sequelize.QueryTypes.SELECT });
await Annoucement.destroy({
where: { id: req.params.id }
}
).then((result) => {
console.log(result);
res.status(200).json({ success: true })
}).catch((err) => {
console.log(err)
res.status(400).json({ success: false, errors: err.errors })
});
}
The QueryType you send tells Sequelize how to format the results. If you are performing SET and send QueryType.SELECT you will get an error because it tries to use .map() on an object:
const results = await sequelize.query("SET NAMES utf8mb4;", {
type: sequelize.QueryTypes.SELECT }
);
// -> TypeError: results.map is not a function
Sadly, in many places the docs confuse Raw Query (sending SQL in plain text) and using QueryTypes.RAW (which only should be used to format the results of queries that are not SELECT, UPDATE, etc.). Thus, one could assume that if you are making a Raw Query you should use the same QueryType to make the query "raw". At the very least, we should be able to assume it only affects how data is returned. The Sequelize documentation:
If you are running a type of query where you don't need the metadata,
for example a SELECT query, you can pass in a query type to make
sequelize format the results
Confusingly, if you are using a SELECT then none of these examples cause issues:
sequelize.query("SELECT * FROM table");
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.SELECT });
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.UPDATE });
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.RAW });
But if you use RAW on an UPDATE Sequelize tries to map an object 🙄
sequelize.query("UPDATE table SET createdAt = NOW();", {
type: sequelize.QueryTypes.RAW }
);
There was an uncaught error TypeError: results.map is not a function
at Query.handleSelectQuery ([...]/node_modules/sequelize/lib/dialects/abstract/query.js:261:24)
at Query.formatResults ([...]/node_modules/sequelize/lib/dialects/mysql/query.js:123:19)
at Query.run ([...]/node_modules/sequelize/lib/dialects/mysql/query.js:76:17)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async [...]/node_modules/sequelize/lib/sequelize.js:619:16
So, because you are using SET you could, as #Anatoly says, change from QueryTypes.SELECT to QueryTypes.RAW to avoid the error. But if you don't need the results then don't pass a QueryType at all.
await sequelize.query('SET FOREIGN_KEY_CHECKS=0;');
// -> keep on keepin' on

How to fix 'UnhandledPromiseRejectionWarning: ReferenceError:'?

I'm participating on this event called Semana OmniStack 9.0, on which we are currently developing the backend of an app on NodeJS with MVC and MongoDB, so in one of my controllers there is this error popping up 'UnhandledPromiseRejectionWarning: ReferenceError: Spot is not defined' which I tried to solve, but with no luck.
I already checked and compared my code with the Lecturer's, I think that I'm messing up with something on the async await side of JS, which I never have coded before.
This is my SpotController:
const spot = require('../models/Spot');
module.exports = {
async store(req, res) {
const { filename } = req.file;
const { company, techs, price } = req.body;
const { user_id } = req.headers;
const spot = await Spot.create({
user: user_id,
thumbnail: filename,
company,
techs: techs.split(',').map(tech => tech.trim()),
price
});
return res.json(spot);
}
};
And this is the Spot model for the DB (which is MongoDB):
const mongoose = require('mongoose');
const SpotSchema = new mongoose.Schema({
thumbnail: String,
company: String,
price: Number,
techs: [String],
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Spot', SpotSchema);
And after I run Insomnia (it's a program similar to Postman), the app crashes and throw this error:
(node:13956) UnhandledPromiseRejectionWarning: ReferenceError: Spot is not defined
at store (C:\Users\sadkevin\Desktop\Programs\Rocketseat\SemanaOmnistack9\backend\src\controllers\SpotController.js:9:22)
at Layer.handle [as handle_request] (C:\Users\sadkevin\Desktop\Programs\Rocketseat\SemanaOmnistack9\backend\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\sadkevin\Desktop\Programs\Rocketseat\SemanaOmnistack9\backend\node_modules\express\lib\router\route.js:137:13)
at Immediate.<anonymous> (C:\Users\sadkevin\Desktop\Programs\Rocketseat\SemanaOmnistack9\backend\node_modules\multer\lib\make-middleware.js:53:37)
at runCallback (timers.js:706:11)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
(node:13956) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was
not handled with .catch(). (rejection id: 1)
(node:13956) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
After I sent the data with Imsonia it should return me a JSON file, any ideas guys?

Node JS self._callback.apply is not a function error

import axios from 'axios';
import * as jwt from 'jsonwebtoken';
import { Action } from 'routing-controllers';
import { Connection } from 'typeorm';
import { env } from '../env';
export function authorizationChecker(connection: Connection):
(action: Action, roles: any[]) => Promise<boolean> | boolean {
let validationKey: any = axios.get(env.auth.jwksUri).then(response => {
validationKey = response.data.keys[0].value;
}).catch();
return async function innerAuthorizationChecker(
action: Action,
roles: string[]
): Promise<boolean> {
// here you can use request/response objects from action
// also if decorator defines roles it needs to access the action
// you can use them to provide granular access check
// checker must return either boolean (true or false)
// either promise that resolves a boolean value
try {
const token = (action.request.headers.token ||
action.request.headers.authorization).replace('Bearer ', '');
await jwt.verify(token, validationKey);
return true;
} catch (e) {
return false;
}
};
}
This is my error:
error: [app] Application is crashed: TypeError: self._callback.apply is not a
function
(node:512) UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 1): TypeError: Cannot read property '0' of undefined
(node:512) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled
will terminate the Node.js process with a non-zero exit code.
I'm trying to get the validation key set from a specific URL from a service, but somehow (without calling the function) it says that the response data is undefined. On top of that, I'm having this error: self._callback.apply is not a function.
Has someone dealt with such a callback error before? I couldn't find anything on stackoverflow relating to my problem.

Calling a promise in a test get error 400 in NodeJS

I'm trying to use Contentful, a new JS library for building static websites. I want to use it in Node JS.
I created an app file like this (the name is getContent.js):
'use strict';
var contentful = require('contentful')
var client = contentful.createClient({
space: '****',
accessToken: '****'
});
module.exports = client;
function getEntry() {
return client.getEntry('******')
.then(function (entry) {
// logs the entry metadata
console.log(entry.sys)
// logs the field with ID title
console.log(entry.fields.channelName)
})
}
Then I created a test (getContent.test.js) like this:
'use strict';
let chai = require('chai');
let should = chai.should();
var expect = chai.expect;
var rewire = require("rewire");
let getContent = rewire("./getContent.js");
describe('Retreive existing', () => {
it('it should succeed', (done) => {
getContent.getEntry({contentName:'****'
}, undefined, (err, result) => {
try {
expect(err).to.not.exist;
expect(result).to.exist;
// res.body.sould be equal
done();
} catch (error) {
done(error);
}
});
});
});
but I obtain this error:
Retreive existing (node:42572) UnhandledPromiseRejectionWarning:
Error: Request failed with status code 400
at createError (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:886:15)
at settle (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:1049:12)
at IncomingMessage.handleStreamEnd (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:294:11)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9) (node:42572) UnhandledPromiseRejectionWarning: Unhandled promise
rejection. This error originated either by throwing inside of an async
function without a catch block, or by rejecting a promise which was
not handled with .catch(). (rejection id: 3) (node:42572) [DEP0018]
DeprecationWarning: Unhandled promise rejections are deprecated. In
the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
Do you know what I'm missing? the promise is ok, I already tested it with a simple node getContent.js
I am seeing few issues with your code:
1. Invalid Args
In your test function, in getContent.js, you are passing an argument to the getEntry method (return client.getEntry('******'), whereas you are passing an object in the test (getContent.getEntry({}))
2. Mixing Promises & Callbacks
it('it should succeed', (done) => {
getContent.getEntry("****")
.then((result) => {
console.log(result);
try {
expect(result).to.exist;
// res.body.sould be equal
done();
} catch (error) {
done(error);
}
})
.catch(error => {
console.log(error);
done(error)
})
});
3. Source of Unhandled Promise rejection is not clear:
Is it coming from your test function in getContent.js, or, is it coming from your actual test?
Probably, this could also come from,
expect(err).to.not.exist;
expect(result).to.exist;
Always catch errors in Promises and reject it with proper reason to avoid issues like this.
Could you please update your code and repost it, so that its clear for other users?

Categories