Koa pass data from server to client - javascript

I want to pass through some environment variables from a Koa server to the client. In express I could do something like res.render('index', { data: 'someData' }); and then I could access data. In Koa I can't see how to do this. It mentions using context.state but I can't find any example of how to retrieve this in the client.

You can do something similar in Koa, you just need to use the right middleware. Try out koa-views if you're using one of the supported engines.
Here is a full example (this example assumes you're using Koa v1 and EJS as your templating engine):
app.js
const Koa = require('koa')
const views = require('koa-views')
const router = require('./routes')
const app = new Koa()
app.use(views(__dirname + '/views', { extension: 'ejs' }))
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000)
routes.js
const router = require('koa-router')()
router.get('/', function * () {
yield this.render('index', { title: 'Home' })
})
router.get('/about', function * () {
yield this.render('about', { title: 'About' })
})
module.exports = router
Just change the extension argument you pass to the middleware based on which templating engine you are using.

Related

How can I localize routes with the nextJs and next-i18next like an URL alias?

I'm using NextJs 10.0.5 with next-i18next 8.1.0 to localize my application. As we all know nextJs 10 has subpath routing for internationalized routing. In addition, I need to change the page names by language. For example, I have a contact-us file inside the pages folder. When I change the language to Turkish, I have to use localhost:3000/tr/contact-us. However, I want to use localhost:3000/bize-ulasin to access the contact-us page when the language is Turkish. So there are two URLs and only one page file.
It works when I use custom routing with express js in the server.js file. However, when I want to access the "locale" variable within the getStaticProps function in the contact-us file, I cannot access it. The getStaticProps function returns undefined for "locale" variable when I use localhost:3000/bize-ulasin URL.
server.js
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const app = next({ dev: process.env.NODE_ENV !== "production" });
const handle = app.getRequestHandler(app);
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
if (pathname === "/bize-ulasin") {
app.render(req, res, "/contact-us", query);
}else{
handle(req, res, parsedUrl);
}
}).listen(3000, (err) => {
if (err) throw err;
console.log("> Ready on http://localhost:3000");
});
});
/pages/contact-us-file
import { Fragment } from "react";
import Head from "next/head";
import { useTranslation } from "next-i18next";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
const ContactUs = () => {
const { t } = useTranslation("common");
return (
<Fragment>
<Head>
<title>Contact-Us</title>
</Head>
</Fragment>
);
};
export const getStaticProps = async ({ locale }) => {
console.log(locale); // When I use the URL localhost: 3000/bize-ulasin, it returns undefined.
return {
props: {
...(await serverSideTranslations(locale, ["common"])),
},
};
};
export default ContactUs;
How can I access the "locale" variable with getStaticProps? Or, how can I use the following URLs with the same page file?
->localhost:3000/contact-us
->localhost:3000/bize-ulasin
I also faced the same problem today. That's how I solved the issue.
First of all, delete the server.js file. With Next.JS 10, using server.js will create conflict with the i18n routes and you won't be able to get the locale data in getStaticProps.
NextJS has a beautiful method named rewrites. We will use that instead of our server.js file. For example, if you have a page named contact-us-file, we can rewrite our next.config.js file as
const { i18n } = require('./next-i18next.config')
module.exports = {
i18n,
async rewrites() {
return [
{
source: '/contact-us',
destination: '/en/contact-us-file',
},
{
source: '/bize-ulasin',
destination: '/tr/contact-us-file',
},
]
},
}
As you are already using Next-i18next, I hope you are familiar with the file that I am importing.
Now If you try to navigate localhost:3000/contact-us and localhost:3000/bize-ulasin you should be able to access your contact us page.

How to import object to another file?

I'm using Node.js to build a web application.
I have two files. Server.js - where I call the server to go online etc. And the other one is a file which includes a big object with data. I imported the file with data into server.js, I get the object in postman when I set the website to be live. But I can't dive inside the object to get the data inside the object. The error I'm getting says that the variable where my data is stored is not defined.
I think the fix is to import albumsData variable into server.js, but im completely stuck and can't find how to do it. If anyone has any idea, please share.
albumsData.js
const express = require('express');
const router = express.Router();
let albumsData = {
filled with data
}
router.get('/albumData', (req, res) => {
res.send(albumsData);
});
module.exports = router;
Server.js
app.use(require('./api/albumData/unikkatilData'))
app.use((req, res) => {
res.status(404)
.send(albumsData)
});
app.listen(4000, () => {
console.log('hello worldd')
})
If you want the albumsData object then you can do it like this:
In you albumsData.js file:
const albumsData = {
// Bunch of data
}
module.exports = albumsData
Then in your server.js file:
const albumData = require('./api/albumsData') // Make sure this path points directly to the albumsData.js file
move enter code here to new file (ex utils.js)
and export it exports.albumsData = albumsData; then you can call it
with const utils = require('./utils') ; utils.albumsData

Routing for translation url in nodejs express

I would like to know how to do routing for translation url in nodejs express
I have following routes in app.js, I would like to know how to do in a better way, lets say if have more than 5 languages , url will vary according to language but go to same route.
How to do in express nodejs.
app.js
app.use(/^\/(en|de)/, langRouter);
app.use(/^\/(en|de)\/((all-services-from|hui-kuan-cong)-(.+)-(to|zhi)-(.+))/, serviceRouter);
app.use('/:lang/route-services-services/:pr', aboutRouter);
app.use('/:lang/ain-jian-wen-ti/:pr', aboutRouter);
frontend urls,
will pass to langRouter
/en
/de
will pass to serviceRouter
/en/all-services-from-sin-to-mal
/de/hui-kuan-cong-sin-zhi-mal
will pass to aboutRouter
/en/route-services-services/fund
/de/ain-jian-wen-ti/fund
app.use(/:locale*, checkLangRouter);
app.use(/:locale/, langRouter);
app.use(/:locale/:slug/, serviceRouter)
app.use('/:locale/:slug/:pr', aboutRouter);
The first is the middleware to check if the locale is available..
In each router, check the slug depending of the locale. If it's not corresponding, just call the next() method...
//aboutRouter.js
module.exports = (req, res, next) => {
const locale = req.params.locale;
const slug = req.params.slug;
const myMapping = {
en: 'about',
fr: 'a-propos',
it: 'attorno'
};
if (myMapping[locale] !== slug) {
// It's not the about route
return next();
}
};
In this case, a conceil will be to export the mapping in another file to make it readable...

Auth middleware not calling stub - NodeJS, sinon

Similar questions have been asked before & I have looked at & followed them but no luck:
Sinon stub being skipped as node express middleware
node express es6 sinon stubbing middleware not working
How to mock middleware in Express to skip authentication for unit test?
The general answer I get from these is that the module (app.js in my case) should be required AFTER the auth middleware method has been stubbed. I have done this, but still calls the original middleware:
src/app.js
const authentication = require('./authentication')
...
app.use(['/api/users', '/api/groups'], authentication.ensureAuthenticed])
module.exports = app
src/authentication.js
const { isValidAuth } = require('./lib')
exports.ensureAuthenticated = (req, res, next) => {
...
}
__helpers__/supertest.js
// This file just calls endpoints with supertest but this is the only file
// that includes 'app'
const app = require('../../src/app')
module.exports = {
post: {
...
},
get: {
...
},
put: {
...
},
delete: {
...
}
}
users.spec.js
const authentication = require('../../src/authentication')
const authenticationStubs = require('../__stubs__/authentication')
let supertest
let ensureAuthStub
describe('Users', () => {
before(() => {
ensureAuthStub = sinon.stub(authentication, 'ensureAuthenticated').callsFake(authenticationStubs.ensureAuthenticated)
supertest = require('../__helpers__/supertest')
})
// tests
after(() => {
ensureAuthStub.restore()
})
})
__stubs__/authentication.js
exports.ensureAuthenticated = (req, res, next) => {
...
}
In users.spec.js, I load in supertest.js (which loads in src/app.js) AFTER the method has been mocked so I am not sure why the original is still being invoked.
I have also attempted to manually clear the cache before mocking but still does not work.
I think the solution would be using Rewire instead (or with) Supertest.
Rewire lets you to mock top level components of a module. Though you would need to mock middleware before passing to Supertest.
Turns out it was something to do with having supertest.js require app.js. I now have users.spec.js require the app and pass it it into supertest methods as a param. It now works. Still unsure why though

using React router with Next JS route

i have simple question , i am new in Next.JS
we have a project and my web application manage routes in BackEnd with Next JS
now my problem is here , i want use React-Router-dom in one section
forexample before im working with Laravel and React
in Laravel I set My Route like This
Route::get('/reactPage/*' ...)
and then use Clien route with react
but i dont know how handle this with Next JS
( more details => for example i want user click to some link after that user see a page with some link inside of them , if user click that link , react-router-dom handle route and no any request send to Server )
I would recommend using the Next router. You do need to create a custom server in order to overload the default Next routing, but its a trivial task:
// server.js
const { createServer } = require('http');
const next = require('next');
const routes = require('./routes');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = routes.getRequestHandler(app);
app.prepare().then(() => {
createServer(handler).listen(port, err => {
if (err) {
throw err;
}
console.log(`> Ready on http://localhost:${port}`);
});
});
Then you can define routes, which I do in the routes.js file:
// routes.js
const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());
routes
.add('landing', '/')
.add('profile', '/profile', 'profile');

Categories