vite + vuejs 3 Get vue instance at mount() - vuejs3

I am facing something strange.
When I get the vue instance with vue-cli. I get a proxy with $ store, $ router etc. But with 'vite' I get a proxy of proxy from which I can't find $ store etc.
let app = createApp(App)
.use(store)
.use(router)
.mount("#app");
console.log(app);
From vue-cli based app :
From vite based app :
Does anyone know how to get the instance up vite ? Did I miss something?
Thanks by advance. =]

App.vue has been written with script setup. component instances created from such a component definition will have a closed public interface by default.
And createApp(App).mount() returns the instance created from App.vue
If you write App.vue without you will find it has $store etc.
And with , you can use defineExpose() to explicitly expose individual APIs. example:
import { useStore } from 'vuex'
const store = useStore()
defineExpose({
$store: store
})
If you did that in App.vue, you would now find that the logged object has a $store property

Related

Generating dynamic routes in Nuxt with Cloud Firestore using #nuxtjs/firebase

I need some help.
I'm trying to build out my static site on Nuxt which has a bunch of dynamic routes.
So far in my nuxt.config.js I've got
generate: {
async routes() {
const queryDb = await app.$fire.firestore.collection("schools").get()
return queryDb.docs.map(x => `/performance/${x.schoolId}`);
}
}
However, when using Nuxt generate, it fails because it can't read property '$fire' which is how I've been accessing firebase throughout my application (using https://firebase.nuxtjs.org). Is there some way I can require it before creating the routes?
Any help would be appreciated! Thanks.
I also encountered the error:
TypeError: Cannot read property '$fire' of undefined
After following this demo of Nuxt and Firebase, it fixed by adding '#nuxtjs/firebase' inside the buildModules that didn't mention from the tutorial:
nuxt.config.js
buildModules: [
'#nuxtjs/firebase'
],

Firebase Nuxt Does Not Recognize 'location' Object When Trying to Run The Whole App With Firebase Emulator

My firebase Nuxt app was recently converted to SSR from SPA mode. It was all working fine in SPA mode but when I tried to convert it, it generated a lot of errors. I tried to solve them one by one and I'm stuck with the error ReferenceError 'location' was not defined. I want to run my emulator because I want to test my other functions if it is running completely in SSR mode.
import firebaseTmp from "firebase/app";
import firebaseErrorsJa from "~/plugins/firebaseErrorsJa";
import "firebase/storage";
import "firebase/firestore";
import 'firebase/auth';
import 'firebase/functions';
const config = process.env.firebaseConfig;
if (!firebaseTmp.apps.length) {
firebaseTmp.initializeApp(config);
}
const db = firebaseTmp.firestore();
const functions = firebaseTmp.functions();
const firebase = firebaseTmp;
const firestore = firebaseTmp.firestore();
const storage = firebaseTmp.storage();
const auth = firebaseTmp.auth();
const firestoreTimestamp = firebaseTmp.firestore.Timestamp;
const serverTimestamp = firebaseTmp.firestore.FieldValue.serverTimestamp();
const firebaseErrors = firebaseErrorsJa;
if (location.hostname === "localhost") {
db.settings({
host: "localhost:8000",
ssl: false
});
functions.useEmulator("localhost", 5001);
auth.useEmulator('http://localhost:9099/');
}
export { db, firebase, firestore, auth, storage, firestoreTimestamp, serverTimestamp, functions, firebaseErrors }
I imported almost all libraries but still it does not work.
TAKE NOTE: This only happens when it is in SSR mode. Does this mean that location does not work in SSR mode?
I tried to take away the chunk of code that has 'location' in it. It works perfectly well locally but when I try to run my other functions, it generates CORS error. It accesses the link being used when we deploy our functions.
https://us-central1-talkfor-dev.cloudfunctions.net/v1-auth-updateUser
This is the link that was shown in the console
What I expected is that us-central1-talkfor-dev.cloudfunctions.net will be localhost:5000 since we are using the local development.
Do you have any Idea why is it like this?
Alex you understand that SSR mode is trying to render the website on the server. This can be your local running server instance, that means there is no window object for it to access location variable. Location is only accessible inside the browser. The SSR context is not in the browser, hence makes total sense.
Window.location here states.
Server vs Browser environments here states that
Because you are in a Node.js environment... You do not have access to the window or document objects... You can however use window or document by using the beforeMount or mounted hooks.
.
Why don't you try either of these,
use these beforeMount and mounted hooks like this.
beforeMount () {
window.alert('hello');
}
mounted () {
window.alert('hello');
}
using the process.client environment variable
if (process.client) {
// Do your stuff here
// I think this is what you are looking for.
}

Using local emulator for firebase with expo

I am trying to firebase to emulate locally for testing a react native app I am working on with expo. To that end I am trying to set the host of the functions and firestore to the proper port on local host.
After many iterations I finally found a weird combination of imports and calls that did not error. However, when I tried to run it with expo my App came up as a blank screen with no errors.
I am pretty lost at this point and the firebase documentation is confusing.
This is my current index.js:
import firebase from "firebase"
import 'firebase/firestore';
import 'firebase/functions';
import 'firebase/app';
const config = {
//config info
};
const fb = firebase.initializeApp(config);
const firestore = firebase.firestore();
const functions = firebase.functions();
if(__DEV__){
firestore.settings({
host : "localhost:9000",
ssl : false
});
functions.useFunctionsEmulator("http://localhost:5001");
}
const auth = fb.auth();
export { auth, functions, firestore }
The imports are very weird and I don't understand them but I got them from another stack overflow thread and it was the only thing that made it even get to the end of the file. Is there something very obvious I am missing about setting up the local emulator?
the issue you may be having with using the Local Emulator Suite and Expo together is that that "localhost" refers to the device you're using. If you're testing on a physical device, you need to point Firebase to the running instance on your computer. I wrote up a short explainer on it here:
https://dev.to/haydenbleasel/using-the-firebase-local-emulator-with-expo-s-managed-workflow-5g5k
I was able to get this to work on my machine via:
import * as firebase from 'firebase';
import '#firebase/firestore';
import '#firebase/functions';
const firebaseConfig = { /* config data */ }
firebase.initializeApp(firebaseConfig);
firebase.firestore().settings({ host: "localhost:8080", ssl: false });
firebase.functions().useFunctionsEmulator('http://localhost:5001');
In your attempt, I think your problem might be the the way you declared:
const fb = firebase.initializeApp(config);
and then forgot to use the initialized fb -- and instead you used firebase again.
try changing these lines:
const firestore = firebase.firestore();
const functions = firebase.functions();
to this:
const firestore = fb.firestore();
const functions = fb.functions();
or just use the firebase class directly instead of setting to a variable.
Edit:
I noticed that I actually had my firestore store host value set incorrectly so I edited it above - I had added http:// to the beginning but that's not what you want for that parameter.
Note - If you want to see exactly what your dev env is doing when trying to connect to your local firestore, add this line:
firebase.firestore.setLogLevel('debug');
I'm not exactly sure it's your only problem. But for firebase functions to work in an emulator using your android or iphone you need to change
functions.useFunctionsEmulator("http://localhost:5001") to
firebase.functions().useFunctionsEmulator("http://10.0.2.2:5001");
it's for an android emulator only. It's the IP adress of the device you need to reach.
This article does a good job of showing you how to get the right debugger host IP dynamically (if you're running Expo Go on a mobile phone).
basically, it all comes down to:
const origin = Constants.manifest.debuggerHost?.split(":").shift() || "localhost";
firebase.auth().useEmulator(`http://${origin}:9099/`);
firebase.firestore().useEmulator(origin, 8080);
firebase.functions().useEmulator(origin, 5001);

Is it possible to access a real API in React Storybook

I am using Storybook to test my React UI components.
However, when I get to a point where my Action makes an Axios request, I get a 404 response.
Below is the code used in a react action file:
assume the axios instantiation, thunk implementation and action definitions.
getDelayedThunkRes: () => {
return (dispatch) => {
dispatch(delayedResActions.getInitialRes());
axios.get("/test").then(success => {
console.log(success);
}).then(err => {
console.log(err);
})
}
}
localhost:8080 is my real server that I want to connect to. Obviously it should throw me an error because my storybook is running on 9009. How can I connect the two?
Note, it works for my Create React App. Create React App package gives a provision to proxy all the calls to a server using "proxy" field in package.json
Are there any similar tools in Storybook, or is Storybook supposed to be used solely with static mock data?
Alright, I found an amazing post on how to create a middleware for React storybook for APIs
https://medium.com/#wathmal/adding-a-router-middle-ware-to-react-storybook-4d2585b09fc
Please visit the link. The guy deserves the due credit.
Here is my implementation of it in ES5 (somehow Storybook middleware is unable to transpile):
create this middleware.js inside .storybook directory:
const express = require('express');
const bodyParser = require('body-parser');
const expressMiddleWare = function(router) {
router.use(bodyParser.urlencoded({extended: false}));
router.use(bodyParser.json());
router.get('/test', function(req, res) {
res.send('Hello World!');
res.end();
});
}
module.exports = expressMiddleWare
Caveat: You will have to restart Storybook every time you make a change in the middleware.
With this, I am able to make a call from my react actions.
Next, I will try to implement express HTTP proxy middleware to redirect these storybook middleware calls to my real express server.
Edit 1:
The new technique seems to be using decorators, especially with stroybook-addon-headless.
Storybook add on for setting server urls
https://github.com/ArrayKnight/storybook-addon-headless
I am yet to try

Where and how to store API endpoints in vue js?

I am using vue-cli for front-end and lumen for back-end and I am curious about what is a best practice to store API root-url and endpoints in vue ?
Now I have constants.js file in src directory where API root-url and endpoints are like that:
const BASE_URL = "http://localhost:8000"
export const AddLanguge = BASE_URL + "/api/languages"
and when I need for example to implement add language functionality in component I import required API endpoint from constants.js like that:
import { AddLanguge } from '#/constants'
and then use axios to make request
this.$http.post(AddLanguge, params).then(response => {
if (response.status == 200) {
this.addLanguage(response.data.data)
} else {
this.setHttpResponseDialog(response)
}
}).catch(er => {
this.setHttpResponseDialog("Error")
})
I searched this question, but there is no clear answer some say: it's ok.
Others say: it's bad you must store that kind of data in dev.env.js and prod.env.js, and most important fact here is I don't get why are they saying so, why is it important to save that data in .env files? Or maybe is there some other better way?
Can you guys provide a right answer with good explanation or if there is no right answer and it depends on situation how can I decide which way is suitable for my case?
.env files are recommended because you may have different endpoints depending on environment, that is to say are you running dev server with "npm run serve" or building for production with "npm run build". With .env config files they become environment variables and you don't need to hard code them into your app, it's just the most practical thing to do. With Vue CLI 3 you would have
//.env.development
VUE_APP_BASEURL = "http://localhost:8000"
And in your app you could access it with.
process.env.VUE_APP_BASEURL
What I use to do is just have the base in a variable and then concatenate rest.
const BASE_URL = process.env.VUE_APP_BASEURL
this.$http.post(BASE_URL + '/api/languages/', params)

Resources