ES6 Import giving undefined for an object - ecmascript-6

This is a very simple import/export but the import is giving undefined no matter what. I've been following Mozilla's documentation. There's been a number of answers on Stackoverflow, and I've implemented several of the posted solutions, including making the export an object, and a function but nothing is working.
const env = "dev"
const content_dev = {
"artworks" : "http://127.0.0.1:8080/api/arts",
"projects" : "http://127.0.0.1:8080/api/projects",
"notes" : "http://127.0.0.1:8080/api/notes"
}
const content_prod = {
"artworks" : "https://bahlalala.com/api/arts",
"projects" : "https://bahlalala.com/api/projects",
"notes" : "https://bahlalala.com/api/notes"
}
const urls = (env == "dev") ? content_dev : content_prod
console.log(urls) // this is fine
export default urls
Where I'm doing the import.
import urls from "../../urlProvider"
console.log(urls) // undefined
Update: ok, so this works on the back-end but I need it to work in the browser. I have got babel and webpack for the SSR react app, but would module exports not work on the front end?

Related

Reading from JSON

I'm trying to read my i18n-strings from a JSON file following this guide.
I have en-US.json:
{
"world": "the world!"
}
And for setting up my Vue app I use:
import { createI18n } from 'vue-i18n'
import enUS from '../src/i18n/en-US.json'
// Type-define 'en-US' as the master schema for the resource
type MessageSchema = typeof enUS
const i18n = createI18n<[MessageSchema], 'en-US'>({
locale: 'en-US',
messages: {
'en-US': enUS
}
})
This works. But as soon as I add one non-ASCII char (e.g. "world": "the w#rld!"), I get the following error message:
[plugin:vite-plugin-vue-i18n] Cannot read properties of undefined (reading 'message')
/home/bernhard/wd/quasar2-project/src/i18n/en-US.json
Strangely, this works when I do the following straight in my .ts file:
const enUS = {
"world": "the w#rld!"
}
so maybe something wrong with the way the JSON is processed?
The answer has two layers.
As #jonrsharpe pointed out, there is a set of special characters: { } # $ | - i.e. for inserting variables. A # should i.e. be replaced by {'#'}.
A bug in how vite processes external json as described on this bug on Github. By default, quasar is using "#intlify/vite-plugin-vue-i18n": "^3.3.1". Changing that to "#intlify/vite-plugin-vue-i18n": "^7.0.0" solved the issue.

How can I import a JSON file on Next.js on build?

I just want to do a simple thing: import a JSON file and read it within a function to return some specific data of it, but it's been really hard to do.
When on dev env, it works perfectly, but when I try to do the build, the file is not fount. It's like it's not being imported. Since I'm new with Next.JS architecture, I'm not able to find a solution by myself (read a lot of pages with help, but no success).
structure
- root
- config
- labels
data.json
index.ts
index.ts
import data from './data.json';
export type HomeLabels = typeof data.in.home;
export function getHomeLabels(language: string): HomeLabels {
return data[language as keyof typeof data].home;
}
data.json
{
"in":{
"home":{
"contact_button": "Contact",
"view_all_button": "View all"
}
},
"pt-br":{
"home":{
"contact_button": "Contato",
"view_all_button": "Ver tudo"
}
}
}
error on build
TypeError: Cannot read properties of undefined (reading 'home')
at getHomeLabels (/home/runner/work/boutme/boutme/.next/server/chunks/261.js:42:43)
All the solutions that I found out was related to using API or getStaticsProps and using on component. But I really don't want it. I think that it's possible to do what I want (import json and read just on a function), but it's been hard.

Vue - i18n custom translations

I have VUE app with vue-i18n plugin.
I would like to load 'custom path' for translations when app is loaded.
The app is not loading the translations? What am I doing wrong?
File: i18n/index.js
/* eslint-disable */
import { createI18n } from "vue-i18n";
import Message from "#/localization/MyCity/en.json"
const i18n = createI18n({
// default locale
locale: "en",
// translations
messages: Message
});
export default i18n;
File: main.ts
import i18n from "./i18n";
const app = createApp(App).use(i18n)
app.mount("#app");
I tried the code above and the translations are not loading. Do you have any suggestions? This even might be the wrong approach to this problem. Do you have any other suggestion.
Topic 2:
Later on I will try and make dynamic translations based on deployment. I would like to make it fast and simple so I was thinking creating .env file with variable MY_CITY_NAME and do it like this import Message from "#/localization/${MY_CITY_NAME}/en.json".
I guess your problem might be that you are not specifying language of your Messages object.
Try this:
const i18n = createI18n({
...
messages: {
en: Message
}
});

Error.invalid json response Unexpected token T in JSON at position 0 sanity nextjs typscript [duplicate]

This question already has an answer here:
Fetch error when building Next.js static website in production
(1 answer)
Closed 4 months ago.
hey i guys i have a question i did the build with react and typscript and sanity cms but the problems is when im trying to deploy the build to varcel it keeps rejecting it sayning that FetchError: invalid json response body at https://portfolio2-1-wn3v.vercel.app/api/getExperience reason: Unexpected token T in JSON at position 0 while it works on my local machine it find all the data and everything ... i read that it might be a problem somewhere down the line with getStaticProps or when fetching json and yes i did change the enviroment varibals from base_url in http 3000 to the varcel ones but other than that i have no idea what else i should do .... if anyone has any expirince with this kind of errors ? here is my code for the
`import {Experience} from '../typings'
export const fetchExperiences = async () =>{
const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/getExperience`)
const data = await res.json()
const projects:Experience[] = data.experience
return experience
}`
the getExercise.ts file has all the api request
import type{NextApiRequest,NextApiResponse} from 'next'
import {groq} from 'next-sanity';
import {sanityClient} from '../../sanity';
import {Experience} from '../../typings'
const query = groq`
*[_type == "experience"]{
...,
technologies[]->
}
`;
type Data ={
experience:Experience[]
}
export default async function handler(
req:NextApiRequest,
res:NextApiResponse<Data>,
){
const experience:Experience[]= await sanityClient.fetch(query)
res.status(200).json(JSON.parse(JSON.stringify({experience})))
}
and this is the index.ts file part
export const getStaticProps: GetStaticProps<Props> = async() => {
const experience : Experience[] = await fetchExperiences();
const skills : Skill[] = await fetchSkills();
const projects : Project[] = await fetchProjects();
const socials : Social[] = await fetchSocials();
return{
props:{
experience,
skills,
projects,
socials,
},
revalidate:10
}
}
The error link you see (https://portfolio2-1-wn3v.vercel.app/api/getExperience) is the preview deployment link from vercel. That means, everytime you deploy to vercel it will create this preview link: https:// yourappname-(some unique deployment link).vercel.app.
However, in your api you pass ${process.env.NEXT_PUBLIC_BASE_URL} which will work on your local and probable on production, but it will not on your preview deployments (staging).
To avoid this, unfortunately you cannot only give /api/getExperience as only absolute URL's are supported. Therefore, I suggest the following approach by avoiding the API call as suggested in the [nextjs docs][1]:
you create an experience-queries.ts file in lib/
you add your GROQ query in there
export const getExperiences = groq`*[_type == "experience"]{..., technologies[]->}`
In index.ts, in getStaticProps you call getExperiences
const experiences = await sanityClient.fetch(getExperiences);
Note: Be careful with naming between experience (one single item) and experiences (a list of items) -> make sure you name if as you intend to get them.
[1]: https://nextjs.org/docs/basic-features/data-fetching/get-static-props#write-server-side-code-directly

import json in javascript doesn't seem to succeed

In a firebase functions project I want to have some settings in a settings.json and then import the settings in my typescript files. For some reason, the import doesn't seem to succeed and I can't see or figure out why.
My folder/file structure looks like this:
src
- database
- index.ts <-- only exports uppercase.ts
- uppercase.ts
- regions.ts
In uppercase.ts I import regions.ts to use the functions object with the configuration to deploy on europe-west1.
import { functionsEUWest1 } from '../regions';
export const uppercase = functionsEUWest1.database.ref('/messages/{pushId}/original').onCreate((snapshot, context) => {
//Code as can be found in the tutorials of firebase.
});
In the regions, I try to read the settings from settings.json to use for the configuration.
import functions from 'firebase-functions';
import settings from "./settings.json";
const region: any = settings.region;
export const functionsEUWest1 = functions.region(region);
And this is the content of settings.json
{
"region": "europe-west1"
}
The folder/file structure of the build output is the same (only in lib instead of src but this is by default configured by firebase).
When I try to deploy my functions, I get the following error:
Error: Error occurred while parsing your function triggers.
TypeError: Cannot read property 'region' of undefined
at Object.<anonymous> (<local basepath>\functions\lib\regions.js:9:57)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (<local basepath>\functions\lib\database\uppercase.js:3:19)
at Module._compile (module.js:653:30)
When I look into the build output in the file regions.js, I can't detect any rarity of transpiled code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const firebase_functions_1 = __importDefault(require("firebase-functions"));
const settings_json_1 = __importDefault(require("./settings.json"));
const region = settings_json_1.default.region;
exports.functionsEUWest1 = firebase_functions_1.default.region(region);
//# sourceMappingURL=regions.js.map
Also the settings.json is copied to the build location and is in the same folder as regions.js. Yet the property default from setting_json_1 is undefined and I can't figure out what goes wrong.
Edit
I added 2 settings to the tsconfig.json. I did this cause it was advised in several articles I found:
"resolveJsonModule": true,
"esModuleInterop": true
After some more research I came up later on, I figured out it wasn't the json import that didn't seem to work, but it looks like the setting
"esModuleInterop": true
doesn't seem to work together with firebase or perhaps more specific: firebase functions, for so far as I can see and conclude.
The research to the conclusion
First I wanted to figure out if import in TypeScript does work at all, so I created 3 .ts files and one .json file and one of the .ts files I put in a folder. Then I generated the tsconfig.json with
tsc --init
and I added the 2 settings (resolveJsonModule and esModuleInterop). I transpiled the .ts files to .js files and ran the code with node. And this works, I saw the setting value from the .json file printed in the console.
The .ts file that imported the .json file has these lines of code:
import settings from "./settings.json";
console.log('from test.ts: ' + settings.setting1);
export const Settings = settings;
This got transpiled to:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var settings_json_1 = __importDefault(require("./settings.json"));
console.log('from test.ts: ' + settings_json_1.default.setting1);
exports.Settings = settings_json_1.default;
Now, I don't understand this code completely because I don't know what __importDefault or mod are.
But this code along with the other code does do what it suppose to do: read the setting from the .json file and print it in the console. So importing .json files does work. So it got to do something with firebase.
The next step I did, was creating a clean firebase project which uses functions and hosting. In the by the firebase CLI genrated index.ts in the functions/src folder, I changed the code to this:
import functions from 'firebase-functions';
import settings from "./settings.json";
const setting1 = settings.setting1;
export const helloWorld = functions.region('europe-west1').https.onRequest((request, response) => {
response.send("Hello from Firebase! Settings1 value = " + setting1);
});
And I also added the same 2 settings to tsconfig.json (resolveJsonModule and esModuleInterop). When I try to deploy this function to the firebase cloud, I got an error that is the same as I mentioned in my Question post:
TypeError: Cannot read property 'region' of undefined
But this time, I didn't had a property region in my .json file. So the fact I had region in my code in the question post and the fact I didn't look at the line numbers of the stacktrace, mislead me, making me think the .json import didn't work. But it is working.
The cause of the error is the method region that is called on the firebase_functions_1.default. For some reason, default is undefined and that is generating the error. This made me also realise I really miss the name of the object or objects in the error. What I would like to see is something like
TypeError: Cannot read property 'region' of undefined (firebase_functions_1.default)
So, back to the problem, I still got the error, but it wasn't cause by the .json import. To figure out what the actual cause was, I first reverted the "esModuleInterop" setting in the tsconfig.json, which results in errors in the import section in my index.ts. I had to change the imports back to
import * as functions from 'firebase-functions';
import * as settings from "./settings.json";
And now, the deploy to the firebase cloud works again, with importing a .json file. Also, the transpiled code looks different without using the "esModuleInterop" setting:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const functions = require("firebase-functions");
const settings = require("./settings.json");
const setting1 = settings.setting1;
exports.helloWorld = functions.region('europe-west1').https.onRequest((request, response) => {
response.send("Hello from Firebase! Settings1 value = " + setting1);
});
//# sourceMappingURL=index.js.map
It no longer has the default property on firebase_functions_1 but instead now just has functions.
It depends on some of your build and tsconfig settings. I've seen the above working for some people, where it uses the default export. But for me (Webpack with json-loader) this is what I use to import JSON files:
import * as settings from "./settings.json";
And of course, in my case, I add a definition like so to my global.d.ts file:
declare module "*.json";
Just so TS won't complain about it.