Get language from nuxt.js middleware - javascript

Is there a way in nuxt.js middleware to know the language used for the request (of the page)?
By taking the example proposed by nuxt.js (https://nuxtjs.org/api/pages-middleware/) and by supposing that for example a page declined in two languages (French and English) with the following urls:
/fr/ma-page
/en/my-page
When visiting the first or second url, can we have an indicator on the language used directly in the middleware? Or should you parse the page url to find out (route)?
Because I want to redirect the user according to the language requested...

If you're using nuxt-i18n module, is really simple, and you have two ways of doing it. I'll suggest the first, but I think it would be cool to give a perspective on how the module works.
Both of the solutions have the same starting point, getting the i18n from the middleware context. i18n should be accessed from the app parameters from the context, so we start from here:
export default async function({ app: { i18n } }) {}
1. The best way: letting the i18n module do the hard lifting
The same way you can access the translations inside Vue components using the $t method, we could use it from the i18n object directly.
So if you would write in a Vue Component
$t('components.login.register')
Then in the middleware you would do
i18n.t('components.login.register')
2. Other option: getting to know the i18n module better
If you inspect the i18n object that the module exposes, you can find the following parameters is contains:
locale - That represents the current language
messages - An object that keeps the translations for each active language
so you could easily get the previous example translation like this:
const { messages, locale } = i18n
const currentTranslations = messages[locale]
const wantedTranslation = currentTranslations.components.login.register
I'd suggest for you to use the i18n.t module, as it works some of the abstractions you'd need to rewrite yourself, but it's a good example to understand the module better.

Related

Dependancy injection using Tsyringe for multiple implementation of interface in Typescript

Context
I am currently working on a Typescript Lambda project where we are planning to refactor our code to make use of dependency injection using the Tsyringe library. We have a typical MVC structure for projects except instead of the Repo/Database layer we have a proxy layer which calls a third-party service over the rest API to fetch the required data.
The catch is that the proxy layer will have a single interface defined and it will have multiple implementations among which one needs to be injected depending upon the business decision. For example AuthProxy is an interface which contains a login method, and it has two different implementation classes KeycloakAuthProxyImpl and AuthZeroAuthProxyImpl. These two implementations will be in 2 separate folders say AuthZero and KeyCloak and while building we pass an argument like --folderName so only one implementation will be available in runtime for dependency injection.
The problem
The problem we are facing with Tsyringe (I have evaluated some other libraries too) is that interface-based dependency injection needs explicit token-based registration with ioc-container in the main.ts page(In my case, the handler function file). So as per theory, I should be registering it as follows.
.
But in our case, this is not possible. Because say we are building it as --keycloak as an argument, then AuthZearoAuthProxyimpl will be ignored while compiling and hence the code will break in line 14 at runtime.
We tried to move that dependency registration logic to the corresponding implementation class so that each implementation class will be self-contained and isolated so that there won't be any runtime issues. But then these are not even being registered for dependency injection and we get an error saying Attempted to resolve unregistered dependency token: "AuthProxy". This is expected as per the file loading of javascript.
KeycloakImpl class.
.
We even tried using #registry decorator which can be found commented in the images, but it also didn't make any difference.
Even though I haven't tried any other dependency injection libraries of Typescript, from my little research, most of them follow more or less the same pattern for interface-based dependency injection and I am anticipating the same issue in those also. Is there any other workaround through which I can resolve this issue, or is it even possible with typescript?
PS: I don't have much expertise in js and typescript, the above keywords are based on my experience with spring and java. Please ignore if I have misused any js specific terminologies while explaining the issue.
Code and project structure
I had similar problems with tsyringe and I found a much better approach.
Here is how I would solve this with a different DI lib iti and also remove many lines of code:
import { createContainer } from "iti"
import express from "express"
// import other deps
const container = createContainer()
.add({
authProxy: () =>
Math.random() > 0.5
? new KeycloakAuthProxyImpl()
: new AuthZearoAuthProxyImpl(),
})
.add((ctx) => ({
authService: () => new AuthServiceV3(ctx.authProxy),
}))
.add((ctx) => ({
server: () => {
const app = express()
app.all("/login", async (req, res) => handler(req, ctx.authService))
return app
},
}))
// start your server / lambda
const server = container.get("server")
server.listen(3000)
I've also refactor other parts of the app and got rid of singletons and made code IMO a bit simpler to read
I’ve created an interactive playground with a mock your app:
https://stackblitz.com/edit/json-server-ntssfj?file=index.ts
Here are some links to the lib:
https://github.com/molszanski/iti
https://itijs.org/

How to check/test the output of a function without compiling the app in React?

Let's say that I have a class in javascript with a method that takes a number and multiplies it by two:
class Foo {
timesTwo(n) {
return n * 2;
}
...
}
const foo = new Foo();
foo.timesTwo(2); // returns 4
What I'd normally do if I wanted to check the output would be to run node foo.js and see the output on my console.
Now I'm going to use a real life example in React, I'm trying to query something from my database (in this case firebase), It'll look something like this:
import firebase from 'firebase'
import 'firebase/firestore';
class User {
constructor() {
this.auth = firebase.auth();
this.db = firebase.db();
}
getUsers() {
// code that queries the db for
// all users and returns them
}
...
}
const user = new User();
user.(getUsers); // returns all users
If I wanted to quickly check the output of that method my original approach doesn't work (probably because this is more than just vanilla javascript), if I try to run node user.js a bunch of errors regarding the imports and ems modules appear.
My biggest delay while programming is having to test the output of something; waiting for the app to compile and then going to that specific screen (react & react-native) to see what the console.log() says. My question is: is there any way I could get the output of a specific function / method without having to compile my entire app?
I've tried solving the issues with the ems modules by importing the libraries by specific path with no luck. And I've checked some testing libraries, most of which specify that their main goal is to test user-related interactions and not functions or methods, but if there's any way that I could use one of these libraries to get the output of a method inside a class based component or a functional component without doing the steps I described above that'll save me incredible amounts of time. So far I haven't been able to find examples on how to do this with a testing library.
If the output is determined by a specific set of user interaction, it is tough to avoid doing it without compiling the entire app. Your suggested way of console.log right before the return method would work, otherwise places you can insert a console.log can be in componentDidMount and componentDidUpdate. This is an ES6 approach to testing things.
If the output is very easily replicable, and able to be encapsulated into an API instead of a client app interaction, I recommend you just do it as a regular NodeJS project preferably in your backend, especially when the logic is rather heavy and requires more testing. That would allow you to use your node user.js method on the command line. This is an ES5 approach to testing things.

A clean way to allow React shared component to get configuraiton property without having to pass it all the way down

I have about 8 simple UI's for different applications, all of them make use of a shared components library I also produce. I recently added a feature to modify how querying is done in the low levels of a some utility functions used in all the saga of all my UIs.
I want each of my UIs to be able to include an optional configuration value to tweak this new querying logic in their configuration files. However, the method that needs the property is very low level, I'd prefer not to have to add an extra property to 5-6 methods to pass one value down to the method that needs it.
These shared components are used only for my UI, which all have a standard format. As such I don't need them to be fully generic, I have no complaint with hard coding their checking the standard location of my configuration file in my UIs. However, since the shared components are a separate NPM package I don't know how to reference the location of a configuration file in the applications calling the UI.
Is there any clean way to get the value from the configuration file other then just passing it through all the relevant methods?
It's simple. You can create configuration file where you'll export your logic. And when you need that config, import that and use. Here's an example:
configuration.js
export const test = (myvar) => {
return 'test: ' + myvar
}
component.js
import { test } from 'configuration.js'
test('pass') // test: passed

Svelte framework: pass environment variables to client-side bundle at runtime

Posted this to the Svelte repo as well:
I just made my first Svelte app over the weekend, and really liked the experience. One thing I'm curious about, that I wasn't able to figure out with a decent amount of research, is if/how one could pass a runtime env var or similar to a client-side script so it's available in the bundle/browser. This probably isn't considered a "best practice", so maybe I'm just on my own here, but in Pug for example you can do something like the following (from a Hapi.js route handler for example):
const context = {
foo: bar,
baz: ''
}
return h.view('index', context)
These vars are then available in the Pug context.
In my toy app I wanted to make it possible to pass an api key at server start time (either from a .env or CLI), and inject that from the Express server like so:
app.use(express.static(`${__dirname}/public`))
and have that var be available in the client script. Again, it's probably not a best practice to be injecting api keys into client-side scripts and making calls from there, but is this kind of variable passing possible in Svelte?
It seems like this should be possible using either rollup-plugin-inject or rollup-plugin-replace, but I wasn't able to figure out how to make that work. This is definitely not a criticism of the framework, but perhaps a section on working with env vars would be a useful addition to the Svelte docs. Thanks!
Typically this is the sort of thing you would do in your build config. From the rollupjs tag I'll assume you're using that — you could use rollup-plugin-replace to inject the content you need:
// rollup.config.js
import replace from 'rollup-plugin-replace';
import svelte from 'rollup-plugin-svelte';
export default {
input: 'src/main.js',
output: {
file: 'public/bundle.js',
format: 'iife'
},
plugins: [
svelte(),
replace({
// you're right, you shouldn't be injecting this
// into a client script :)
'API_KEY': process.env.API_KEY
})
]
};

Service, get & extend in javascript and how are they being used

I am trying to make sense of some code snippets in javascript. But getting way too confused, it seems to be using all the symbols in all possible ways.
import Ember from 'ember';
export default Ember.Route.extend({
metrics: inject.service(),
activate() {
this._trackPage();
},
_trackPage() {
run.scheduleOnce('afterRender', this, () => {
const page = document.location.href;
const title = this.routeName;
get(this, 'metrics').trackPage({ page, title });
});
}
});
q1: What are the keyword service, get, extend? What are they doing here?
q2: Why is activate defining _trackPage separately? Why not put the reschedule code in activate() itself?
Basically trying to understand: https://emberway.io/applying-the-adapter-pattern-for-analytics-in-ember-js-apps-29448cbcedf3
A service is a place to put code that can be used almost anywhere in the app. In order to make the code inside a service available to the script you're working on, you inject it.
get is a helper that is used to access things like the service or Ember objects. In more recent tutorials, you'll see syntax that looks more like this.get('metrics'). See the docs here.
You could put the _trackPackage code into the activate function if you wanted to. However, activate is a special function called a hook, and many developers like to keep their route hooks like activate as short and sweet as possible for stylistic reasons. Hooks are special functions that fire automatically on things like a user entering a route, rerenders, etc. There are many kinds of hooks like this throughout Ember.
Extend is Ember boilerplate that gets created for you when you use the Ember CLI to make new files. Basically, when you create a route, you're extending on Ember's default route configurations, attributes, and methods. So there's some base behavior (like the activate hook) that gets inherited.
I recommend that you read the Ember Guides sections on objects and services for more info.

Categories

Resources