Ember FastBoot SimpleDOM body is empty - javascript

I'm trying to read from the DOM in an instance initializer in the FastBoot environment but document.body seems to be empty. The following code works in the browser but returns nothing in FastBoot:
const ELEMENT_NODE_TYPE = 1;
// TODO(maros): Get this working with FastBoot. For some reason the SimpleDOM
// body is empty.
const findBootstrapData = (document) => {
for (let currentNode = document.body.firstChild; currentNode; currentNode = currentNode.nextSibling) {
if (currentNode.nodeType !== ELEMENT_NODE_TYPE) {
continue;
}
if (currentNode.getAttribute('class') === 'bootstrap-data') {
return JSON.parse(currentNode.firstChild.nodeValue);
}
}
};
export function initialize(appInstance) {
const store = appInstance.lookup('service:store');
const document = appInstance.lookup('service:-document');
const data = findBootstrapData(document);
if (data) {
store.push({ data: data.posts });
}
}
export default {
name: 'blog-posts',
initialize
};
The data that I'm trying to read has been injected into the {{content-for "body"}} section using an Ember CLI addon. This works perfectly without FastBoot.
How can I get this instance initializer working in FastBoot?
Edit:
For extra context, here's how I'm populating the DOM using an Ember CLI Addon:
/* eslint-env node */
'use strict';
const fs = require('fs');
const path = require('path');
const convertMarkdown = require('marked');
const parseFrontMatter = require('front-matter');
// Reads blog posts from `/posts`, compiles from markdown to HTML and stores
// as JSON in a script tag in the document. An instance initializer then picks
// it up and hydrates the store with it.
module.exports = {
name: 'blog-posts',
contentFor: function(type) {
if (type !== 'body') {
return;
}
const dirname = path.join(__dirname, '..', '..', 'posts');
const data = fs.readdirSync(dirname).map((filename, index) => {
if (!filename.endsWith('.md')) {
return;
}
const fileContent = fs.readFileSync(path.join(dirname, filename), 'utf-8');
const frontMatter = parseFrontMatter(fileContent);
return {
id: index + 1,
type: 'post',
attributes: {
title: frontMatter.attributes.title,
body: convertMarkdown(frontMatter.body),
},
};
});
return `
<script class="bootstrap-data" type="text/template">
${JSON.stringify({ posts: data })}
</script>
`;
}
};

document.body will always be empty during the app boot lifecycle. Since the rendering is not done yet (during the instance initializer phase), the fastboot placeholders aren't replaced.
You could do either of the following:
You could use the shoebox API to push and get the fastboot bootstrap data : http://ember-fastboot.com/docs/user-guide#the-shoebox
If you want to do it outside the app lifecycle, then you could do it after fastboot.visit request is done and after result.html() is called.

Related

CoinbaseWalletSDK does not work with server side rendering

I was trying to load CoinbaseWalletSDK in my NextJS application, but it always throw an error of ReferenceError: localStorage is not defined due to it was imported before the window is loaded. I tried dynamic loading but it doesn't work. The following is what I am using at this moment.
export async function getServerSideProps({
params,
}: {
params: { project_id: string };
}) {
const project_id = params.project_id;
let project: any = fakeProjects[0];
if (project_id && typeof project_id === 'string' && !isNaN(parseInt(project_id))) {
const id = project_id;
project = fakeProjects.find(p => p.id === parseInt(id));
// Fetch project detail here
let item = await (
getNFTStatsByProjectId(
parseInt(project_id)
)
);
if (project && item && item['nftTotal'] && item['nftSold']) {
if (item.nftSold > item.nftTotal) {
item.nftSold = item.nftTotal;
}
project.nftTotal = item.nftTotal;
project.nftSold = item.nftSold;
}
}
const { coinbaseEth } = (await import('../../components/services/coinbase'));
return {
props: {
project: project,
coinbaseEth: coinbaseEth
},
};
}
And this is what I have in the coinbase service:
// TypeScript
import CoinbaseWalletSDK from '#coinbase/wallet-sdk'
import Web3 from 'web3'
const APP_NAME = 'Practice App'
const APP_LOGO_URL = process.env.WEBSITE_URL + '/logo.png'
const DEFAULT_ETH_JSONRPC_URL = 'https://mainnet.infura.io/v3/' + process.env.INFURA_PROJECT_ID
const DEFAULT_CHAIN_ID = 1
// Initialize Coinbase Wallet SDK
export const coinbaseWallet = new CoinbaseWalletSDK({
appName: APP_NAME,
appLogoUrl: APP_LOGO_URL,
darkMode: false
})
// Initialize a Web3 Provider object
export const coinbaseEth = coinbaseWallet.makeWeb3Provider(DEFAULT_ETH_JSONRPC_URL, DEFAULT_CHAIN_ID)
// Initialize a Web3 object
export const web3 = new Web3(coinbaseEth as any)
The new CoinbaseWalletSDK is where the error was thrown if that's a concern.
Based on my research, I will need to get it imported after the page is fully loaded (which is the point when "window" become available, as well as "localStorage"), which I have no clue how to achieve. Can anyone help me out on this?
I solved it by loading it later. What I did was to assign this variable with this function.
setTimeout(async () => {
coinbaseEth = (await import('../../components/services/coinbase')).coinbaseEth;
}, 1000)
I choose not to use useEffect because the value will be lost on render, which prevents the function to work properly.

Getting the Site URL in Next.JS [duplicate]

I want to get the page's full URL or site hostname like the image below on Static Site Generator.
I will try with window.location.hostname, but it doesn't work.
The error: window not defined.
If you want the hostname inside getInitialProps on server side, still you can get it from req
Home.getInitialProps = async(context) => {
const { req, query, res, asPath, pathname } = context;
if (req) {
let host = req.headers.host // will give you localhost:3000
}
}
With server-side rendering (getServerSideProps), you can use context.req.headers.host:
import type { GetServerSideProps, NextPage } from "next";
type Props = { host: string | null };
export const getServerSideProps: GetServerSideProps<Props> =
async context => ({ props: { host: context.req.headers.host || null } });
const Page: NextPage<Props> = ({ host }) => <p>Welcome to {host || "unknown host"}!</p>;
export default Page;
But with static generation (getStaticProps), the hostname is not available, because there is no request to get it from. In general, a server doesn't know its own public hostname, so you need to tell it. Using Next.js environment variables, put this in .env.local:
HOST=example.com
Then access it with process.env['HOST']:
import type { GetStaticProps } from "next";
export const getStaticProps: GetStaticProps<Props> =
async context => ({ props: { host: process.env['HOST'] || null }});
If you want to get the full URL:
import { useRouter } from 'next/router';
const { asPath } = useRouter();
const origin =
typeof window !== 'undefined' && window.location.origin
? window.location.origin
: '';
const URL = `${origin}${asPath}`;
console.log(URL);
The place where you are accessing the window make sure you add a check so that code is executed only on the browser and no during SSG"
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
}
Update:
If you have specified basePath in next.config.js:
module.exports = {
basePath: 'https://www.example.com/docs',
}
Then using useRouter, you can access the base path:
import { useRouter } from 'next/router'
function Component() {
const router = useRouter();
console.log({ basePath: router.basePath});
// { basePath: 'https://www.example.com/docs' }
...
}
But if you have a relative base path then you can use the first approach
Consider this package > next-absolute-url
import absoluteUrl from 'next-absolute-url'
const { origin } = absoluteUrl(req)
const apiURL = `${origin}/api/job.js`
If you deployed your Next.js app with now the apiURL will be something like https://your-app.now.sh/api/job.js.
However, if you are running the app locally the apiURL will be http://localhost:8000/api/job.js instead.
Using typeof window !== 'undefined' is the secure way. if (window) {} will run you into problems.
const hostname = typeof window !== 'undefined' && window.location.hostname ? window.location.hostname : '';
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
Using above code will give you the frontend/outside hostname/origin the client using: example.com, www.example.com, www.example.com:80 and so on, not the localhost stuff. useRouter() will return the server side hostname/origin (localhost, localhost:3000)
I believe you're better of doing this with a combination of useRouter and useEffect hooks. In my case I wanted to dynamically set the og:url of my webpage. This is what I did. We have router.pathname as a dependency so that ogUrl is updated every time we move to a different page.
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
const MyComponent = () => {
const router = useRouter();
const [ogUrl, setOgUrl] = useState("");
useEffect(() => {
const host = window.location.host;
const baseUrl = `https://${host}`;
setOgUrl(`${baseUrl}${router.pathname}`);
}, [router.pathname]);
return <div></div>
}
You need to ensure your access to window.location.hostname happens on the client-side only, and not during server-side rendering (where window does not exist). You can achieve that by moving it to a useEffect callback in your component.
function Component() {
useEffect(() => {
console.log(window.location.hostname)
console.log(window.location.href) // Logs `http://localhost:3000/blog/incididunt-ut-lobare-et-dolore`
}, [])
// Remaining code of the component
}
req.headers are Symbols and not Objects, so to get value, you use the get method
const host = req.headers.get("host"); // stackoverflow.com
AFAIK there are two ways of doing this:
Next JS provides us with the useRouter hook, first you have to import it in your component, then, to use the router object, you just have to declare it. For example:
const router = useRouter();
console.log(router.pathname);
const {pathname} = router; <---- To access the pathname directly.
Besides this, as #Xairoo said before, if you want to use the window object, you have to check if window !== 'undefined' to avoid errors. The window not defined error happens because Next JS use NodeJS to render the app and the window object is not defined in Node JS.
You can find a more detailed explanation in this link.
none oh the answers above solved the problem and this is the solution i figured it out :
function return_url(context) {
if (process.env.NODE_ENV === "production") {
// if you are hosting a http website use http instead of https
return `https://${context.req.rawHeaders[1]}`;
} else if (process.env.NODE_ENV !== "production") {
return "http://localhost:3000";
}
}
and on the getServerSideProps or getStaticProps functions you use
export async function getServerSideProps(context) {
let url = return_url(context);
const data = await fetch(`${url}/yourEndPoint`).then((res) => res.json());
return {
props: {
data: data,
},
};
}
Using a middleware.js file that you add to the root of your project can give you access to the host name and provide a lot of flexibility to perform actions based on it if needed.
https://nextjs.org/docs/advanced-features/middleware
// Example: redirecting a domain to a subdomain
import { NextResponse } from "next/server";
// This function can be marked `async` if using `await` inside
export function middleware(request) {
// Currently there is no main site so we redirect to the subdomain.
const host = request.headers.get("Host");
if (
process.env.NODE_ENV === "production" &&
host.startsWith("mydomain.com")
) {
return NextResponse.redirect(new URL("https://mysubdomain.mydomain.com"));
} else if (
process.env.NODE_ENV === "staging" &&
host.startsWith("staging.mydomain.com")
) {
return NextResponse.redirect(
new URL("https://mysubdomain-staging.mydomain.com")
);
}
}
in Next.js you can do like this,
by useEffect to get window.location.origin in client side,
and set it to state.
work fine in :
{
"next": "12.1.6",
"react": "18.1.0",
}
const Home: NextPage = () => {
const { asPath, query } = useRouter();
const [loading, setLoading] = useState(false);
const [loginCallBackURL, setLoginCallBackURL] = useState("");
useEffect(() => {
setLoginCallBackURL(
`${window.location.origin}/${query.redirect ? query.redirect : "user"}`,
);
}, []);
// if you do something like this, it can't get loginCallBackURL
// const loginCallBackURL = useMemo(() => {
// if (typeof window !== 'undefined') {
// return `${window.location.origin}/${
// query.redirect ? query.redirect : "user"
// }`;
// }
// return asPath;
// }, [asPath, query]);
return (
<div>
<Button
variant="contained"
href={queryString.stringifyUrl({
url: `${publicRuntimeConfig.API_HOST}/auth/google/login`,
query: {
callbackURL: loginCallBackURL,
},
})}
>
Sign in with google
</Button>
</div>
);
};
export default Home;
We can get current url like this:
import { useRouter } from 'next/router';
const router = useRouter();
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
const address_url = origin+router.asPath;

info argument is empty in Apollo GraphQL resolver type signature

I'm working on this library https://github.com/ilyaskarim/wertik-js called Wertik JS to make GraphQL + Rest API more easily, In resolvers, when I console log info, it shows undefined. For each module, I have created dynamic resolvers to make things more easy for developers who will use this library.
let object = {
create: async (_:any, args:any, context:any,info: any) => {
console.log(info); // This will be undefined
let v = await validate(validations.create,args.input);
let {success} = v;
if (!success) {
throw new ApolloError("Validation error",statusCodes.BAD_REQUEST.number,{list: v.errors})
}
try {
let createModel = await model.create(args.input);
pubsub.publish(`${camelCase(moduleName)}Created`, { [`${camelCase(moduleName)}Created`]: createModel });
return createModel;
} catch (e) {
return internalServerError(e);
}
},
}
Line: https://github.com/ilyaskarim/wertik-js/blob/ec813f49a14ddd6a04680b261ae4ef2aadc2b1a5/src/framework/dynamic/resolvers.ts#L102
The info is described in Apollo Server Documentation https://www.apollographql.com/docs/apollo-server/essentials/data/#resolver-type-signature, Which says: This argument contains information about the execution state of the query, including the field name, the path to the field from the root, and more. For me, unfortunately, it is getting undefined.
To reproduce the issue:
Download https://github.com/ilyaskarim/wertik-js/tree/development
Yarn install
Go to examples/demo
Run node index.js
Now go to http://localhost:1209/
Enter this mutation for example:
mutation {
createRole(input: {name: "Asd"}) {
name
}
}
This line executes on this mutation https://github.com/ilyaskarim/wertik-js/blob/ec813f49a14ddd6a04680b261ae4ef2aadc2b1a5/src/framework/dynamic/resolvers.ts#L102
And returns undefined on the console.
This is how I setup the application:
const { ApolloServer } = require('apollo-server');
import mutations from "./loadAllMutations";
import queries from "./loadAllQueries";
import resolvers from "./loadAllResolvers";
import subscriptions from "./loadAllSubscriptions";
import schemas from "./loadAllSchemas";
import generalSchema from "./../helpers/generalSchema";
export default function (rootDirectory: string,app: any,configuration: object) {
let allMutations = mutations(rootDirectory);
let allQueries= queries(rootDirectory);
let allSchemas = schemas(rootDirectory);
let allResolvers = resolvers(rootDirectory);
let allSubscriptions = subscriptions(rootDirectory);
let {validateAccessToken} = require(`${rootDirectory}/framework/predefinedModules/user/auth`).default;
let mainSchema = `
${generalSchema}
${allSchemas}
type Subscription {
${allSubscriptions}
}
type Mutation {
${allMutations}
}
type Query {
${allQueries}
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
`;
const server = new ApolloServer({
typeDefs: mainSchema,
resolvers: allResolvers,
context: async (a: any) => {
await validateAccessToken(a.req);
}
});
server.listen(1209).then(({ url, subscriptionsUrl }) => {
console.log(`Server ready at ${url}`);
console.log(`Subscriptions ready at ${subscriptionsUrl}`);
});
}
What could be a possible reason?
You're truncating the parameters received by the resolvers inside this module. If you need to assign a function to some object property, it's much better to just do it like this:
mutations: {
[`create${moduleName}`]: mutations[`create${moduleName}`],
},
This is not only more succinct, but it also means you don't risk accidentally leaving off a parameter, which is what happened here.

How can I make static variable in `module.exports = class` in node.js

How can I initialize a static variable in module.exports = class in node.js.
Basically, what I'm trying to achieve is, if StaticVariable is null, Ill get data from a json file. Then store it in StaticVariable.
module.exports = class Config {
static fetch() {
if ( StaticVariable === null ) {
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
}
Function fetch() will be called several times so it is unnecessary to readFileSync every call.
Static-only class is an antipattern in JavaScript because a class is never instantiated.
In case there's a need to have a method that lazily loads JSON file, a plain object can be used. There's already such object in module scope, module.exports:
const fs = require('fs');
let StaticVariable;
exports.fetch = () => {
if ( StaticVariable == undefined ) { // not "=== null"
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
There may be no need to parse it manually because this could be handled by require('./config.json') one-liner and with more consistent relative paths.
In case JSON file can be eagerly loaded, this can be simplified to:
exports.config = require('./config.json');
If there's a need for Config class and it should access configuration object, it can refer to it, e.g.:
exports.Config = class Config {
constructor() {
this.config = deepClone(exports.config);
}
modify() {
// modify this.config
}
};
I can think of several ways to achieve what you are asking.
Saving it in a global variable
//initialise it here
var StaticVariable = null;
//however if you initialise it here, it makes more sense to just load it once
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
module.exports = class Config {
static fetch() {
return StaticVariable;
}
}
Or just use require. Require will do the same thing what you want to do. It will read the file config.json, try to parse it as a valid json and it will do this only once.
module.exports = class Config {
static fetch() {
return require('./config.json');
}
}
Starting from (node 15.2.1) ES2020, static private class fields is supported. So from now on static class may not be anti pattern and you can instantiate a class using new keywords. ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
module.exports = class Config {
static #StaticVariable = null;
static fetch() {
if ( StaticVariable === null ) {
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
}
Where # sign means private more reference can be found in https://node.green, but still the easiest way is described in other answers
exports.config = require('./config.json');

Webpack shows parent scope as undefined

EDIT: I have just gone through the process of switching back to browserify and am having the same problem. So no longer a webpack problem. Still need help though
I am in the process of switching from broswerify to webpack. I have created an abstraction for my ajax calls. In that file I have some private variables that I use to set URL and timeout etc. For some reason it shows these variables (and the entire 'closure') as undefined, leading to some weird bugs. This code was working perfectly fine with browserify.
This is my webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
devtool: 'source-map',
entry: path.resolve(__dirname, 'src', 'client', 'index.js'),
output: {
path: path.resolve(__dirname, 'public'),
publicPath: 'localhost:3002',
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader',
},
],
},
plugins: [
new webpack.DefinePlugin({
__API_URL__: JSON.stringify('http://localhost:3002/api'),
}),
],
};
This is my api wrapper api.js
import request from 'superagent';
import store from './store';
import { system, account } from '../core/actions';
const API_URL = __API_URL__;
const TIMEOUT = 10000;
const _pendingRequests = {};
function getJwt() {
/**
* This retrieves the JSON Web Token from local or session storage
* We simply try both so that we don't have to subscribe to the store
* and make sure some flag is constantly updated. The reducer that handles
* the successful login will place the token in the proper place.
*/
let token = localStorage.getItem('JWT_TOKEN');
if (token) {
return 'Bearer ' + token;
}
token = sessionStorage.getItem('JWT_TOKEN');
if (token) {
return 'Bearer ' + token;
}
return null;
}
function addRequest(key, pendingRequest) {
_pendingRequests[key] = pendingRequest;
}
function abortPendingRequests(key) {
if (_pendingRequests.hasOwnProperty(key)) {
_pendingRequests[key]._callback = () => {
};
_pendingRequests[key].abort();
_pendingRequests[key] = null;
}
}
function digest(resolve, reject) {
return function consume(err, res) {
if (err && err.timeout === TIMEOUT) {
return store.dispatch(system.apiTimeout());
} else if (res.status === 401) {
return store.dispatch(account.logout());
} else if (!res.ok) {
return reject(res);
} else {
if (err) {
return reject(err);
} else {
return resolve(res.body);
}
}
};
}
export function get(actionType, resource) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.get(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
export function post(actionType, resource, data) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.post(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
if (data) {
requested.send(data);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
export function put(actionType, resource, data) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.put(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
if (data) {
requested.send(data);
}
requested.end(digest(resolve, reject));
});
}
export function del(actionType, resource) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.del(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
There are some weird comments that are the result of trying to debug the problem. But basically, if I set a breakpoint at const _pendingRequests = {}; it shows API_URL and TIMEOUT as being set properly. But if I set a breakpoint at const url =${API_URL}${resource}; in export function get it shows them as undefined as I will show with screenshots.
One thing I am just noticing is that it is breaking on the child scope prior to breaking on the parent scope. I am guessing that has something to do with it, but I am not sure how to change this behavior. I work in node so I have written this like I would write it for the server.
This is the file where I am importing api.js
import * as api from '../../core/api';
import { endpoints } from '../../constants';
export const FETCH_LOOKUPS = 'FETCH_LOOKUPS';
export const FETCH_LOOKUPS_SUCCESS = 'FETCH_LOOKUPS_SUCCESS';
export function fetchLookupsSuccess(lookups) {
return {
type: FETCH_LOOKUPS_SUCCESS,
lookups,
};
}
export function asyncFetchLookups() {
return dispatch => {
return api.get(FETCH_LOOKUPS, endpoints.LOOKUP)
.then(lookups => dispatch(fetchLookupsSuccess(lookups)));
};
}
export const FETCH_LANG = 'FETCH_LANG';
export const FETCH_LANG_SUCCESS = 'FETCH_LANG_SUCCESS';
export function fetchLangSuccess(language) {
return {
type: FETCH_LANG_SUCCESS,
language,
};
}
export function asyncFetchLang() {
return dispatch => {
return api.get(FETCH_LANG, endpoints.LANGUAGE)
.then(language => dispatch(fetchLangSuccess(language)));
};
}
Started digging into the transpiled code and found this
function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TIMEOUT = exports.API_URL = undefined;
exports.get = get;
exports.post = post;
exports.put = put;
exports.del = del;
var _superagent = __webpack_require__(427);
var _superagent2 = _interopRequireDefault(_superagent);
var _store = __webpack_require__(430);
var _store2 = _interopRequireDefault(_store);
var _actions = __webpack_require__(444);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var API_URL = exports.API_URL = ("http://localhost:3002/api"); /**
* This file serves as a wrapper for any ajax requests that need to be made
* - contains a generic call for PUT, POST, GET and DELETE request
* - always attempts to append a JSON Web Token if present
* - keeps track of all pending requests and aborts identical requests
*/
var TIMEOUT = exports.TIMEOUT = 10000;
As you can see it initially sets TIMEOUT and API_URL as undefined. It then exports get, post etc and then sets TIMEOUT and API_URL but that is after the exported get is already being accessed. Not sure why it sets them to undefined or how to fix this behavior.
According to how you require (probably import) the get function babel may transpile first the get function and hand it over to node's require which then evals it.
You then don't have API_URL transpiled yet. This looks like an edge case.
Instead of using the ES6 export, just for this file, use module.exports and use node's require to import it to dismiss that kind of bug.
If this works, try importing instead of requireing (and the way around exporting instead of using module.exports) to narrow the bug.
Note: This is more a hint/workaround than a solution. You may provide the file from where you make the require, this might be useful for other people to answer you.
The problem had to do with the function being called prior the javascript finishing parsing I guess. (Still not sure why) The workaround I found was to attach my initialization function to the window object and call it in an IIFE at the body of my HTML.

Categories

Resources