calling mutli api in node express react - node.js

I am developing custom search engine when people search for somthing my search engine fetch all search engine api that I added and get results to my search engine , i am already added google custom search api now i need to add yahoo and goduckduck so how I can added other api and make my search engine fetch several api ?
const express = require('express');
const bodyParser = require('body-parser');
const logger = require('morgan');
const { SearchController } = require('./routes/search.js');
const { OutlineController } = require('./routes/outline.js');
const path = require('path');
const compression = require('compression');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const app = express();
app.use(compression());
app.use(express.static(path.resolve('../', 'build')));
app.use(bodyParser.text());
app.use(logger('dev'));
app.use('/search', SearchController);
app.use('/outline', OutlineController);
const port = process.env.PORT || 1337;
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
import * as express from 'express';
const { Router } = require('express');
const path = require('path');
const { get } = require('axios');
const router: express.Router = Router();
router.get('*', (req: express.Request, res: express.Response, next: express.NextFunction): void => {
res.sendFile(path.resolve('../', 'build/index.html'));
});
router.post('/:query/:start?', async (req: express.Request, res: express.Response) => {
const { query, start } = req.params;
try {
const { data: { items } } = await get(`
https://www.googleapis.com/customsearch/v1?key=AIzaSyBexWro6lOuVcfmR5uSFvd-jVY8uee45OA&cx=000950167190857528722:vf0rypkbf0w&start=${start
? start
: 10}&q=${encodeURI(query)}`);
console.log('this');
res.send(items);
} catch (error) {
console.error(error);
}
});
export const SearchController = router;
const { Request, Response, Router } = require('express');
import * as express from 'express';
const request = require('request');
const unfluff = require('unfluff');
const router: any = Router();
router.post('/:site(*)', (req: express.Request, response: express.Response) => {
const site = req.params.site;
request(site, (err: Error, res: any, body: any) => {
const data = unfluff(body);
response.send({
title: data.title,
text: data.text
});
});
});
export const OutlineController = router;

Related

Why is the request body empty and the responce status is 404?

I am trying to build a web application using MVC pattern, but I have a problem with POST-request to "http://localhost:5000/api/device": postman POST request attempt
The problem only occurs on POST request, GET request is OK: get request
Code:
index.js
const express = require('express')
const sequelize = require('./db')
require('dotenv').config();
const path = require('path')
const models = require('./models/models')
const cors = require("cors")
const app = express();
const router = require('./routes/index')
const fileUpload = require('express-fileupload')
const errorHandler = require('./milddleware/ErrorHandlingMiddleware')
app.use(cors())
app.use(express.json())
app.use(express.static(path.resolve(__dirname, 'static')))
app.use(fileUpload({}))
app.use('/api', router)
app.use(errorHandler)
const PORT = process.env.PORT || 5000;
const db_start = async ()=>
{
try
{
await sequelize.authenticate();
await sequelize.sync();
app.listen(PORT, ()=>{console.log(`Server started on port ${PORT}`)})
}
catch (e)
{
console.log(e);
}
}
db_start()
routes/index.js
const Router = require('express')
const router = new Router();
const deviceRouter = require('./deviceRouter')
const typeRouter = require('./typeRouter')
const brandRouter = require('./brandRouter')
const userRouter = require('./userRouter')
router.use('/user', userRouter)
router.use('/device', deviceRouter)
router.use('/brand', brandRouter)
router.use('/type', typeRouter)
module.exports = router
routes/deviceRouter.js
const Router = require('express')
const DeviceController = require('../controllers/deviceController')
const router = new Router();
router.post('/', DeviceController.create)
router.get('/', DeviceController.getAll)
router.get('/:id', DeviceController.getOne)
module.exports = router
controllers\deviceController.js
const uuid = require('uuid')
const path = require('path')
const {Device} = require('../models/models')
const ApiError = require("../errors/ApiError")
class DeviceController
{
async create(req, res, next)
{
console.log(req);
try{
const {name, price, brandId, typeId, info} = req.body;
const {img} = req.files;
let fileName = uuid.v4() + ".jpg";
img.mv(path.resolve(__dirname, '..', 'static', fileName));
const device = await Device.create({name, price, brandId, typeId, img: fileName});
return res.json(device);
}
catch(e)
{
next(ApiError.badRequest(e.message));
}
}
async getAll(req, res)
{
const {brandId, typeId} = req.query
let devices;
if(!brandId && !typeId)
{
devices = await Device.findAll()
}
if(brandId && !typeId)
{
devices = await Device.findAll({where: {brandId}})
}
if(!brandId && typeId)
{
devices = await Device.findAll({where: {typeId}})
}
if(brandId && typeId)
{
devices = await Device.findAll({where: {brandId,typeId}})
}
return res.json(devices)
}
async getOne(req,res)
{
}
}
module.exports = new DeviceController()
I logged the request and saw that the request body came up empty and req.files is undefined.
I compared these router and controller with others and found no differences in structure.
What am I doing wrong?
You cannot retrieve files of form-data directly from req.files.
Use formidable (it's an npm package) to parse form-data and work with it easily. Here are the steps:
Run npm install formidable.
Import formidable and fs package in your controller script with:
const formidable = require('formidable')
const fs = require('fs');
Change your create function with this:
async create(req, res, next) {
let form = new formidable.IncomingForm()
form.keepExtensions = true
form.parse(req, async (err, fields, files) => {
// console.log('err', err)
// console.log('fields', fields)
if (err) {
next(ApiError.badRequest(err));
return;
}
const { name, price, brandId, typeId, info } = fields; // <-- fields contain all your text data. it's like req.body
const { img } = files; // <-- it should work now!
let fileName = uuid.v4() + ".jpg";
fs.writeFileSync(path.resolve(__dirname, '..', 'static', fileName), img);
const device = await Device.create({ name, price, brandId, typeId, img: fileName });
return res.json(device);
}
}

How to redirect to localized route in node.js express

I'm using the official i18n library to localize my Angular Universal app and am using a proxy to serve the localized versions.
My app works fine as long as there is a language present in the url (e.g: /en/page), but doesn't work otherwise (e.g: / or /page). I get the error Cannot GET / whenever I try to access a page without the locale in the url.
How do I redirect the user to the localized version of the page using the accept-language header of the request? If I try it with the code below, it creates a redirect loop and the page doesn't load.
server.run.js
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
function app() {
const server = express();
server.use(cookieParser());
server.use('/', (req, res, next) => {
const languages = ['en', 'de', 'fr'];
languages.forEach((locale) => {
const appServerModule = require(path.join(__dirname, locale, 'main.js'));
server.use(`/${locale}`, appServerModule.app(locale));
});
locale = (req.headers['accept-language'] || '').substring(0, 2);
if (!languages.includes(locale)) {
locale = 'en';
}
res.redirect(`/${locale}`)
});
return server;
}
function run() {
app().listen(4200, () => {
console.log(`Node Express server listening on http://localhost:4200`);
});
}
run();
I managed to solve it like this:
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
function app() {
const server = express();
server.use(cookieParser());
const languages = ['en', 'de', 'fr'];
languages.forEach((locale) => {
const appServerModule = require(path.join(__dirname, locale, 'main.js'));
server.use(`/${locale}`, appServerModule.app(locale));
});
server.get('/(:locale(en|fr|de)/)?*', (req, res, next) => {
const { urlLocale } = req.params;
const userLocale = (req.headers['accept-language'] || '').substring(0, 2);
if (urlLocale !== userLocale) {
res.redirect(userLocale + req.url);
}
});
return server;
}
function run() {
app().listen(4200, () => {
console.log(`Node Express server listening on http://localhost:4200`);
});
}
run();

typescript application routes

I make simple instagram api application and I have problem with my routes, export and import. i get error TypeError: Router.use() requires a middleware function but got a undefined
at Function.use (C:\Documents\Desktop\digi.me\node_modules\express\lib\router\index.js:458:13)
at Object. (C:\Documents\Desktop\digi.me\lib\routes\routes.js:12:8)
I have two routes userRouter that go on localhost:3000
and mediaRouter that go on localhost:3000/media
my userRouter.ts
import request, { post } from "request"
import express from "express"
import { Router } from 'express';
const app = express()
const token: any = process.env.INSTAGRAM_TOKEN
export const userRouter = Router()
userRouter.get("/", (req: any, res: any) => {
const url = 'https://graph.instagram.com/17841403377847296/?access_token='+token+'&fields=account_type,media_count,username'
request({ url: url, json: true }, (error: string, response: any) => {
if(error){
res.send("unable to connect to service")
}else{
res.send("USER " + response.body.username + " HAVE " + response.body.media_count + " POSTS")
}
})
})
my mediaRouter
import request, { post } from "request"
import express from "express"
import {Post} from "../models/Post"
import { Router } from 'express';
const token: any = process.env.INSTAGRAM_TOKEN
export const mediaRouter = Router()
mediaRouter.get("/media", (req: any, res: any) => {
console.log(0);
const url = 'https://graph.instagram.com/17841403377847296/media?fields=id,media_url,timestamp&access_token='+token+''
request({ url: url, json: true }, (error:string, response: any) => {
if(error){
console.log('error');
res.send("unable to connect to service")
} else {
const array = response.body.data
var Posts: Post[] = [];
array.forEach(function (obj: any) {
Posts.push(new Post(obj.media_url, obj.timestamp))
});
res.send(Posts);
}
})
})
my routes.ts
import { Router } from 'express';
import userRouter from "./routes"
import mediaRouter from "./routes"
import express from 'express';
const app = express();
const routes = Router();
routes.use('/', userRouter);
routes.use('/media', mediaRouter);
export default routes
and my main app.ts
import express from "express"
import * as dotenv from "dotenv"
import routes from "./routes/routes"
const app = express()
dotenv.config();
//envirements variable for port
const port: any = process.env.PORT
app.use(routes);
app.use(express.json());
//Adding server to port
app.listen(port, () => {
console.log("server is listen on port 3000")
})

typescript can not get page

I have an app that uses instagram api and has two route index "/" and media "/". Index is working fine but media doesn't work. It doesn't enter in get method. I made them in the same wa but one is working and the other doesn't.
I'm using typescript and node.
And I cant find the error.
My media route:
import request from "request"
import express from "express"
import { Router } from 'express'
import { Post } from "../models/Post"
const app = express()
const token: any = process.env.INSTAGRAM_TOKEN
const mediaRouter = Router()
mediaRouter.get("/media", (req: any, res: any) => {
const url = 'https://graph.instagram.com/17841403377847296/media?fields=id,media_url,timestamp&access_token='+token+''
request({ url: url, json: true }, (error: string, response: any) => {
if(error){
res.send("unable to connect to service")
}else{
const array = response.body.data
var Posts: Post[] = [];
array.forEach(function (obj: any) {
Posts.push(new Post(obj.media_url, obj.timestamp))
})
res.send(Posts);
}
})
})
export default mediaRouter
my user "/" rout (that work)
import request from "request"
import express from "express"
import { Router } from 'express'
const app = express()
const token: any = process.env.INSTAGRAM_TOKEN
const userRouter = Router()
userRouter.get("/", (req: any, res: any) => {
const url = 'https://graph.instagram.com/17841403377847296/?access_token='+ token +'&fields=account_type,media_count,username'
request({ url: url, json: true }, (error: string, response: any) => {
if(error){
res.send("unable to connect to service")
}else{
res.send("USER " + response.body.username + " HAVE " + response.body.media_count + " POSTS")
}
})
})
export default userRouter
and my main app.ts
import express from "express"
import dotenv from "dotenv"
import userRouter from "./routes/userRouter";
import mediaRouter from "./routes/mediaRouter";
const app = express()
dotenv.config();
//envirements variable for port
const port: any = process.env.PORT
app.use("/media", mediaRouter)
app.use("/", userRouter)
//Adding server to port
app.listen(3000, () => {
console.log("server is listen on port "+ port +"")
})
Remove the "/media" path from mediaRouter. Since its declared twice, the resulting path will be GET /media/media instead of GET /media:
mediaRouter.get("/", (req: any, res: any) => {})

Export object or variable between units or modules in node js

I need export an object or variable from my app to a router module.
The object is called "page" into "ClientClass".
I read something in SO and I tried to use a global var to save the object, exports it on end of unit.
This object will be used in the router module.
But, I have no success. In the router module "page" is always undefined.
How could I do that?
Main App JS - ClientClass.js:
const express = require('express');
const app = express();
const WARoutes = require('./routes/WARoutes');
var globalpage;
export default class ClientClass {
constructor(options) {
this.options = ...
}
async start() {
const browser = ....
const page = await browser.newPage();
// set globalpage to export
globalpage = page;
console.log('Done!');
app.use(express.json({ limit: '20mb' }));
app.use('/whats', WARoutes);
app.listen(port, () => {
console.log(`Listening on ${this.callbackUrl}...`);
});
}
start();
};
module.exports.page =globalpage;
WARoutes.js:
const express = require('express');
const router = express.Router();
const pagebrowser = require('../ClientClass.js');
const page = pagebrowser.page;
router.get('/getChats', async (req, res) => {
const chats = await page.evaluate((includePict, done) => {
do sometthing; //Here is my problem - page is undefined
}, includePict, done);
res.send(chats);
});
module.exports = router;
You have a cyclical dependency. You need to pass your page variable to the WARoutes.js implementation. Here's one way to do it:
WARoutes.js:
const express = require('express');
const router = express.Router();
//export a function which takes the `page` variable, *returning* the router which used to be _exported_
module.exports = function(page){
router.get('/getChats', async (req, res) => {
const chats = await page.evaluate((includePict, done) => {
do something;
}, includePict, done);
res.send(chats);
});
return router;
}
ClientClass.js:
const express = require('express');
const app = express();
const WARoutes = require('./routes/WARoutes');
export default class ClientClass {
constructor(options) {
this.options = ...
}
async start() {
const browser = ....
const page = await browser.newPage();
console.log('Done!');
app.use(express.json({ limit: '20mb' }));
app.use('/whats', WARoutes(page));
app.listen(port, () => {
console.log(`Listening on ${this.callbackUrl}...`);
});
}
start();
};
P.S.
I am also curious about what you're passing to page.evaluate. The first is a function with two arguments, the second and third are those two arguments again. I have a sneaking suspicion this is not going to work even as modified. You're going to need to provide more information about the page.evaluate API for additional help with that.

Resources