Use exported value in setup of Vue Composition API - javascript

In a plain js file the code looks like
export default async function exportData() {
const { data } = await store
.dispatch('fetchData')
const { bookings } = data
const booking = bookings.length ? bookings[0]._id : ''
const event = {
bookingID: booking
}
// other methods and variables
return {
.....
}
}
inside the vue file
import exportData from './exportData'
export default {
setup() {
const {
fetchEvents,
isEventActive,
} = exportData()
fetchEvents()
}
}
the problem is in vue components the values from exportData gets undefined, gets error fetchEvents is not a function when the export is asynchronous. works well if not asynchronous. what is the workaround here??

You can try to declare fetchEvents,isEventActive methods in plan js file without wrapping it inside any function
const fetchEvents = () => {
//body
};
const isEventActive = () => {
//body
};
and export them as
export {fetchEvents, isEventActive};
now use them
import {fetchEvents,isEventActive} from 'path-to-js-file'
export default {
setup() {
fetchEvents()
isEventActive()
}
}

Related

Importing async function error: Invalid hook call. Hooks can only be called inside of the body of a function component

All I wanna do is be able to call logic from my geolocationApi file into my react-native components whenever I want, NOT LIKE A HOOK but normal async functions, I'm using a custom hook in the geolocationApi file I'm importing though! (custom hooks handles mobx state updates)
I want to call it like this in my functional components (plain and easy):
import geolocationApi from '#utils/geolocationApi.js'
const getCoords = async () =>
{
let result = await geolocationApi().requestLocationPermissions(true);
};
My geolocationApi file where I have a bunch of functions about geolocation I don't want to crowd my components with.
#utils/geolocationApi.js
import _ from 'lodash';
import Geolocation from 'react-native-geolocation-service';
import { useStore } from '#hooks/use-store';
const geolocationApi = () => {
//Custom hook that handles mobx stores
const root = useStore();
const requestLocationPermissions = async (getCityName = false) =>
{
const auth = await Geolocation.requestAuthorization("whenInUse");
if(auth === "granted")
{
root.mapStore.setLocationEnabled(true);
let coords = await getMe(getCityName);
return coords;
}
else
{
root.mapStore.setLocationEnabled(false);
}
};
const getMe = async () =>
{
Geolocation.getCurrentPosition(
async (position) => {
let results = await onSuccess(position.coords);
return results;
},
(error) => {
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
};
/*const onSuccess = async () => {}*/
};
export default geolocationApi;
This can't be that hard!
If I remove export default geolocationApi and instead add export const geolocationApi at the top I get:
geolocationApi.default.requestLocationPermissions is not a function
You cannot use hooks outside React components. You can pass down the state to your function
import geolocationApi from '#utils/geolocationApi.js'
const getCoords = async (root) =>
{
let result = await geolocationApi(root).requestLocationPermissions(true);
};
Then instead of using useStore()
import _ from 'lodash';
import Geolocation from 'react-native-geolocation-service';
import { useStore } from '#hooks/use-store';
// pass the root from top
const geolocationApi = (root) => {
// your logic
return {
requestLocationPermissions,
getMe
}
}
Then somewhere in your component tree, ( an example with useEffect )
import getCoords from 'path'
const MyComp = () => {
const root = useStore();
useEffect(() => {
getCoords(root)
}, [root])
}
As you said, geolocationApi is a regular function, not a React component/hook. So, it isn't inside the React lifecycle to handle hooks inside of it.
You can use the Dependency Injection concept to fix it.
Make geolocationApi clearly dependent on your store.
const geolocationApi = (store) => {
Then you pass the store instance to it.
const getCoords = async (store) =>
{
let result = await geolocationApi(store).requestLocationPermissions(true);
};
Whoever React component calls the getCoords can pass the store to it.
//...
const root = useStore();
getCoords(root);
//...

Export without Render function in React Native

In my React Native application, i am trying to add a component where i'll perform some config tasks but that component won't render anything. I have made the component already but when i import that on App.tsx the fucntion doesn't get called. How to import this following component properly to App.tsx. The component is given below:
var androidVersion = VersionInfo.appVersion;
var iosVersion = VersionInfo.buildVersion;
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const Config = () => {
console.log('check if get called >>',showVersionCodeStatus);
const prevAmount = usePrevious(iosVersion);
useEffect(() => {
if(prevAmount.iosVersion !== iosVersion) {
// process here
}
if(prevAmount.androidVersion !== androidVersion) {
// process here
}
}, [iosVersion,androidVersion])
// return {showVersionCodeStatus};
}
export default Config;
i'm importing the component in my App.tsx like the following:
import './config';
But it doesn't call the Config function. I have tried the following too:
import Config from './config';
That doesn't seem to work too. What am i doing wrong?
Since Config does not render anything, you should export it as a custom hook with a name such as useConfig. Subsequently you can import and use your custom hook in App.tsx, which will then run the config tasks specified in your useConfig custom hook.
useConfig.ts
var androidVersion = VersionInfo.appVersion;
var iosVersion = VersionInfo.buildVersion;
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const useConfig = () => {
console.log('check if get called >>',showVersionCodeStatus);
const prevAmount = usePrevious(iosVersion);
useEffect(() => {
if(prevAmount.iosVersion !== iosVersion) {
// process here
}
if(prevAmount.androidVersion !== androidVersion) {
// process here
}
}, [iosVersion,androidVersion])
// return {showVersionCodeStatus};
}
export default useConfig;
App.tsx
import useConfig from "./useConfig";
export default function App() {
const config = useConfig();
return (
...
);
}

getting error _LoginPage.default is not a constructor

this is my code
/// \<reference types = "cypress" /\>
class LoginPage
{
visit()
{
cy.visit("https://ec2-35-179-99-242.eu-west-2.compute.amazonaws.com:2021/")
}
username(name)
{
const field = cy.get('[id=UserName]')
field.clear()
field.type(name)
return this
}
Password(pwd)
{
const pass = cy.get('[id=Password]')
pass.clear()
pass.type(pwd)
return this
}
Submit()
{
const button = cy.get('[type=submit]')
button.click()
}
}
export default LoginPage
/// \<reference types = "cypress" /\>
import LoginPage from './PageObject/LoginPage'
it('valid test', function()
{
const Login = new LoginPage()
Login.visit()
Login.username('arslan')
Login.Password('123')
Login.Submit()
})
i make object of Login class
const Login = new LoginPage()
but getting error
getting error _LoginPage.default is not a constructor
Try using a named export
export class LoginPage {
visit() {
cy.visit("https://ec2-35-179-99-242.eu-west-2.compute.amazonaws.com:2021/")
}
...
}
and import like this
import { LoginPage } from './PageObject/LoginPage'
You need to use function reserved name before all your functions names or declare the functions like a const using an arrow function like:
function visit()
{
cy.visit("https://ec2-35-179-99-242.eu-west-2.compute.amazonaws.com:2021/")
}
or
const visit = () =>
{
cy.visit("https://ec2-35-179-99-242.eu-west-2.compute.amazonaws.com:2021/")
}

Vue 3 - Options API vs Composition API - Load external file into component

I have the following file which is an external file with functions (language.js). I also have created a other component which needs to use language.js (it needs to use the languageText funcion inside language.js). I did used it in a Composition API component. But now I want to get it working in a Options API component. Please check the function inside methods called languageSelector. Inside this function I want to use the global function from language.js (languageText())
Any help?
Options API template (Form.vue)
<script>
import languageText from '#/composables/language';
export default defineComponent({
name: 'Form',
props: {
processingData: Object,
formData: Object
},
emits: ["gateway"],
components: {
Icon
},
data() {
return {
fieldData: this.formData,
}
},
methods: {
languageSelector(data) {
const h = languageText(data) **I want to USE the FUNCTION here.**
console.log(h)
return languageText(data)
},
}
language.js
import { ref, computed, watch } from 'vue';
import { useI18n } from "vue-i18n";
import { useStore } from "vuex";
export default function language() {
const store = useStore();
const i18n = useI18n();
const language = computed(() => {
return store.getters.currentUser.language;
});
function languageText(json) {
const obj = JSON.parse(json)
return obj[language.value]
}
return {
languageText
}
}

Using `useStore` API with vuex 4.x

Follow the official example to export your own useStore, and then use it in the component.
import { createStore, Store, useStore as baseUseStore } from 'vuex';
export const key: InjectionKey<Store<RootState>> = Symbol();
export function useStore() {
return baseUseStore(key);
}
use in the component
setup() {
const store = useStore();
const onClick = () => {
console.log(store)
store.dispatch('user/getUserInfo');
}
return {
onClick,
}
},
After running, store is undefined.
It can be obtained normally when I use it in the methods attribute
methods: {
login() {
this.$store.dispatch('user/getToken')
}
}
why? how to fix it
In that simplifying useStore usage tutorial, you still need to register the store and key in main.ts as they did. You will get undefined if you don't do this:
// main.ts
import { store, key } from './store'
const app = createApp({ ... })
// pass the injection key
app.use(store, key)
The reason is that baseUseStore(key) has no meaning until that's done.

Categories

Resources