Type definition not found - express

I'm starting using VS Code with expressJs. I've decided to split route in different file by using Route.use function.
In the new file I'd like to have intellisense suggesting me all the methods in the app parameters so i've added the /**#param type {Express} app */ jsdoc. The point is that Intellisense isn't able to find type definitions. What do I have to do to let it find type definition for Express?
Here the code i've wrote:
///<reference path="../../node_modules/#types/express/index.d.ts"/>
/**#param {Express} app */
module.exports=function(app){
app.get('/testRoute',function(req,res){
res.send('Hi, I\'m just a simple test');
});
};

Automatic typings acquisition should automatically pick up those types for normal import
or require statements, so in general you should no longer write /// reference path=.
Try something like:
import express from 'express';
module.exports = function (/** #type {express.Express} */ app) {
app.get('/testRoute', function (req, res) {
res.send('Hi, I\'m just a simple test');
});
};
There's currently a bug when using require that prevents types IntelliSense from working properly. This TypeScript issue tracks a possible solution

Related

An updated approach to testing vuex actions

In the "Testing Actions" documentation, there is a recommendation to use inject-loader in order to mock entire module imports, and their respective dependencies, when unit testing.
For example, you can mock the ../api/shop import found inside the ./actions file with the following:
const actionsInjector = require('inject-loader!./actions')
// create the module with our mocks
const actions = actionsInjector({
'../api/shop': {
getProducts (cb) {
setTimeout(() => {
cb([ /* mocked response */ ])
}, 100)
}
}
})
Unfortunately, that package does not support Webpack 5.
Is there an updated approach, or alternative package, that is recommended?
Thanks #Estus Flask.
The clarification/mixup was that, whilst I was using vi.mock, and it's auto-mocking algorithm :
"...will mock the module itself by invoking it and mocking every
export."
i.e. it still runs the import statements. To prevent this, a factory must be provided (see documentation), e.g.:
vi.mock('module', <factory-here>)
Which then replaces the entire file import.

Why is graphql-tag needed to use Apollo with Nuxt?

I'm trying to understand why most tutorials on Nuxt and Apollo also suggest installing the graphql-tag package.
The #nuxt/apollo module docs say this is optional, if you want to load separated .gql files (as opposed to... writing your queries inline in your components?) And the official Nuxt/Apollo demo uses separated .gql files despite not having graphql-tag installed.
I've read this, but it doesn't really seem to answer my question. It just talks about query parsing.
Can anyone tell me precisely what graphql-tag does and whether (and how, in theory) you'd use Apollo with Nuxt without it installed?
I'm not a graphQL expert but I still achieved to work with it the few last months. At the end, I found out that graphql-tag is only useful when using inline queries directly into your .vue components.
Like in this documentation section
<template>
<div>{{ hello }}</div>
</template>
<script>
import gql from 'graphql-tag'
export default {
apollo: {
// Simple query that will update the 'hello' vue property
hello: gql`query {
hello
}`,
},
}
</script>
Meanwhile, since it's not very flexible, I've ended up importing and using it in Vuex like this
import myGqlQuery from '~/apollo/queries/test.gql'
const actions = {
async myFancyVuexAction({ commit, dispatch }) {
try {
const { errors, data } = await this.app.apolloProvider.defaultClient.query({ query: myGqlQuery })
} else {
// error
}
}
}
With the .gql imported file being written like this
query{
Entity {
things
}
}
For this kind of configuration, you don't need graphql-tag. Also, some people have some flexible configuration inside of their graphql files, they are using vanilla .js files and a mix of their actual GQL query + graphql-tag (needed if it's not a .gql file).
It is also useful if using TypeScript, here is an example: https://github.com/DNature/chef-assignment/blob/master/apollo/queries/index.ts
So yeah, those are my 2cts. Not a pro, but things that I understood from my few months fiddling with GraphQL.

import pdfjslib into vuejs component

I would like to create a viewer PDF files into electron/vuejs application.
I need to use the pdfjs librarie.
For that I installed this package : "pdfjs-dist": "2.6.347"
and in my component vuejs I try to used this by doing this :
import pdfjsLib from "pdfjs-dist/webpack";
This import instruction seeems to be running good. But If a start used this like this :
created()
{
pdfjsLib.getDocument()
}
I throw this error :
Cannot read property 'getDocument' of undefined"
I try lot of tricks but I don't find any solution for use this library in my component.
Anyone have a vuejs project with pdfjslib for viewing pdf ?
This seems to work:
import("pdfjs-dist").then((pdfjsLib) => {
pdfjsLib.getDocument();
});
It can be used inside either created() or mounted(). I'd personally use it in mounted.
Working demo here.
Also note calling getDocument() with no arguments seems to trigger some lib error (but that's outside the scope of current question):
Invalid parameter in getDocument, need either Uint8Array, string or a parameter object

express: project-local middleware extending Express.Request

I am working on a node server based on express and written in TypeScript 1.7. I'm using some project-specific middlewares, that extend the existing express Request or Response interface, but I can't get it completely working yet (without tsc complaining about not finding X in req or res). I've found other questions about this issue, but they are either out of date (I guess) or the solution is not straight forward.
I took a look at the definition of an existing middleware, but I didn't get it working without manually writing separate d.ts files and referencing them in typings/tsd.d.ts. This is my setup:
// middleware/foobar.ts
declare module Express {
export interface Request {
foobar?: string;
}
}
/* my project-related middleware extends the request by `foobar` */
export = function(req: Express.Request, res, next) {
req.foobar = 'FooBar';
next();
};
// main.ts
import express = require('express');
var app = express();
app.use(require('./middleware/foobar'));
app.get('/foobar', (req, res) => {
/* tsc: Property 'foobar' does not exist on type 'Request' */
res.send(req.foobar);
});
What's the best practice for extending express' Request and Response interfaces? If possible, without the need of writing a separated d.ts, manipulating anything within the typings directory or using /// <reference path="..." /> comments.
I've found a solution myself, using this example as a reference. My middleware needs to be wrapped in a declared module, so middleware/foobar.ts looks like this:
declare module Express {
export interface Request {
foobar?: string;
}
}
declare module 'foobar' {
function foobar(req: Express.Request, res, next) {
req.foobar = 'FooBar';
next();
}
export = foobar;
}
It's even a bit more trickier if you are using classes or other imported stuff within your middleware. In my example, my middleware uses my own "EntityManager" class, which is an abstraction to the database connection (mysql for me). My middleware (it's middleware/database.ts for me) looks like this now:
declare module Express {
import { Manager as EntityManager } from 'entity-manager';
export interface Request {
entityManager?: EntityManager;
}
}
declare module 'database' {
import * as mysql from 'mysql';
import { Manager as EntityManager } from 'entity-manager';
/* some middleware-related code */
var pool = mysql.createPool(...);
var entityManager = new EntityManager(pool);
/* *** */
/* the actual exported function */
function database(req: Express.Request, res, next) {
req.entityManager = entityManager;
next();
};
export = database;
}
Note that my EntityManager class is imported twice, once per module declaration. It did not seem to work by just importing it above both modules.
UPDATE
Having the actual code in a declared module ('database' in my case) produces no output in the JS file.
Having that code within a regular module requires the name not being in apostrophes (i.e. hyphens would not be allowed there for example) and doesn't produce a one-function-export code either.
Having the actual code completely out of a module (so there's only the declared Express module with the extended Request) produces correct JS but my text editor can't find entityManager in req anymore.
It seems like I'm needed to put the typings (my own extensions to Express.Request for example) into a dedicated d.ts file, where no actual code is present.

node.js adding new routes having cannot read property

I'm pretty new to Node, so please bear with me if this is really stupid. I'm just trying to add my own routes for a couple of new pages, which are built on a sample app I got from a book. Here are some code of my app.js file:
var express = require('express'),
routes = require('./routes'),
http = require('http'),
path = require('path'),
mongoose = require('mongoose'),
models = require('./models'),
dbUrl = process.env.MONGOHQ_URL || 'mongodb://#localhost:27017/blog',
db = mongoose.connect(dbUrl, {safe: true}),
and here are all the routes definition:
app.get('/', routes.index);
app.get('/studentLogin', routes.user.studentLogin);
app.post('/studentLogin', routes.user.checkID);
app.get('/studentLoginAfter', routes.tutorRequestForm.selectCourse);
app.get('/login', routes.user.login);
app.post('/login', routes.user.authenticate);
app.get('/logout', routes.user.logout);
app.get('/admin', authorize, routes.article.admin);
app.get('/post', authorize, routes.article.post);
app.post('/post', authorize, routes.article.postArticle);
app.get('/articles/:slug', routes.article.show);
The studentLoginAfter route is the one I'm trying to add, but every time I added it, I got an error like this:
app.get('/studentLoginAfter', routes.tutorRequestForm.selectCourse);
^
TypeError: Cannot read property 'selectCourse' of undefined.
But in my tutorRequestForm.js file, I apparently defined my handler like this:
exports.selectCourse = function (req, res, next) {
res.render('selectCourseForm');
};
Is there anything I missed? I thought it's should be very straightforward for adding new routes in this way, but I'm really frustrated at this point. Please help...
Well, you missed to include your tutorRequestForm.js file. I would recommend you to read a good node.js tutorial and also one for express.js. For me, apparently it seems like you didn't get the real concept behind node and in particular express.js.
Nevertheless, you should do something like this:
// All the requires are here...
var tutorRequestForm = require('pathToTheFile/tutorRequestForm');
// All the routes are defined here...
app.get('/studentLoginAfter', tutorRequestForm.selectCourse);
This should then work for you. You've basically forgotten to include your file. Furthermore you are trying to access your function via the routes variable, which actually reflects another file.