0

Here is the simple scenario, I am struggling with

apicontainer.js

import mockApi from './mock-api';
import realApi from './api';
function getApi() {
   return Cookies.get('isMock') ? mockApi: realApi;
}
let api = getApi();
export function changeApi() {
    api = getApi();
}
export default api

somepage.js

import api from './path-to/apicontainer';

After the application gets loaded, If set/remove cookie and call changeApi method, will it change the reference dynamically and returns the right api or Is there a better solution?

3
  • 1
    Have you tried this solution already? Does it work? Regardless, why not just call the getApi() function every time you want the API? Checking cookies is not an expensive operation. Commented Mar 27, 2018 at 22:27
  • import api from { apicontainer } is definitely invalid syntax. Please fix it. Also you're not exporting api? Commented Mar 27, 2018 at 22:30
  • @Bergi I was exporting it, forgot to add it to code snippet. Commented Mar 28, 2018 at 21:33

3 Answers 3

3

Yes, imported bindings are just references to the exported variables. One does not export the value, one makes the variable itself available (readonly from outside, though).

So you can do

// apicontainer.js
import mockApi from './mock-api';
import realApi from './api';
function getApi() {
   return Cookies.get('isMock') ? mockApi: realApi;
}
let api = getApi();
export { api as default }
export function changeApi() {
    api = getApi();
}

// somepage.js
import api, {changeApi} from 'apicontainer'
changeApi();
Sign up to request clarification or add additional context in comments.

Comments

2

Yes, It is possible because ES6 modules export bindings (live connections). Read more here

apicontainer.js

import mockApi from './mock-api';
import realApi from './api';

function getApi() {
   return Cookies.get('isMock') ? mockApi: realApi;
}

export function changeApi() {
    api = getApi();
}
export let api = getApi();

somepage.js

import { api, changeApi }  from './path-to/apicontainer';
// whenever you change the condition (cookie in this case) 
changeApi(); // must call the `changeApi` to update the api reference value

Read more about how ES6 modules works

4 Comments

export default api is the one and only way where this does not work.
@Bergi thanks to point that out. I just update the answer! Btw, I just checked you have the same issue in your code snippet
I think is equivalent with my old snippet intention. In fact, you also have an error in the export default syntax export default let api = getApi() because the default export is valid only with a function or class declaration or expressions (not allowing variable declarations). I think the downvote is unnecessary in my answer. Cheers
Oops, how could I forget that. But no, I didn't have that intention, I specifically did not use export default with an expression - which is the only case where one exports a value, not a live connection (under the hood, a live connection to an invisible constant that gets initialised with the value). Thanks for the edit, I removed my downvote.
0

Yes, mutable exports can be used (abused) in that way - if an export gets reassigned in the original module, it'll be reassigned wherever it's imported, but it's not really recommended. It would be better to have the modules consuming the API to do the proper test to identify which API (the mock or the real) to use, and to import said API directly from the source. You don't really want a variable one module is using to get silently reassigned (from that module's perspective) - it's unclear.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.