I'm trying to mock vue-router's route which I am using in one of my components like route.path . I followed this implementation and the outcome looks like:
vi.mock('vue-router', () => ({
useRoute: vi.fn(() => ({ path: '/signIn' }))
}))
But after running tests I'am getting an error:
TypeError: Cannot read properties of undefined (reading 'path')
Related
I have a Quasar app running Vue 3 and Vuex 4
During app creation my store is accessible when printed and shows the full object. The store is set in app creation with
app.use(store, storeKey)
Which produces a fully hydrated object
{_committing: false, _actions: {…}, _actionSubscribers: Array(0),
_mutations: {…}, _wrappedGetters: {…}, …}
The vuex state works perfectly in my router/index with
export default route (function ({ store }) {
const isLoggedIn = store.state.auth.loggedIn;
This example correctly show the loggedIn value I set in my state, so I assume the vuex side must be setup correctly
My problem is I haven't been able to find a way to access my state from a Vue component
I tried with useStore() in my setup function
setup () {
const $store = useStore()
const loggedIn = computed({
get: () => $store.state.auth.loggedIn,
set: () => { $store.commit('login') }
})
Which produces a console error that
injection "store" not found.
and a loggedIn object of
ComputedRefImpl {dep: undefined, _dirty: true, __v_isRef: true,
effect: ReactiveEffect, _setter: ƒ, …}
I also tried using this.$store in the computed object
computed : {
loggedIn () {
return this.$store.state.auth.loggedIn
}
}
But I just get the error that
Property '$store' does not exist on type '{ loggedIn(): any; }'.
I assume I must be missing something silly. I just want to call $store.commit('login') or $store.dispatch from the single file component
How can I access my Vuex store from the single file .Vue component?
Per user10031694 I tried and got a reader working with mapState
computed : mapState({
loggedIn: state => state.auth.loggedIn,
Which gets {{loggedIn}} to show the correct field
I am wondering how to use <TestContext> as a sufficient tool for testing react-admin custom components view. So far we have not encountered an error rendering basic HTML element inside <TestContext>, but with RA component test are failing mostly due to:
TypeError: Cannot create proxy with a non-object as target or handler
In our case, we do not have a redux store connected to our component and for now, just want to test the display with simple props using an example from documentation.
describe('<EditManufacturer/>', () => {
let testUtils: any;
beforeEach(() => {
const mockEditManufacturerProps = {
basePath: '/',
id: '123',
resource: 'foo',
};
testUtils = render(
<TestContext>
<EditManufacturer {...mockEditManufacturerProps}/>
</TestContext>)
});
// test
})
});
Example syntax above produces another error:
Cannot read property '{"type":"GET_ONE","resource":"foo","payload":{"id":"123"}}' of undefined
Here is our EditManufacturer.tsx component:
const EditManufacturer:React.FC<EditProps> = props => {
return(
<Edit {...props}>
<SimpleForm>
<ManufacturerInputFields/>
</SimpleForm>
</Edit>
)};
export default EditManufacturer;
Is injecting all the required props for HOCs and then mounting the view as mentioned in answer here or using e2e tests the only solution? Any help would be appreciated.
Problem: In my vue-cli 4 app, I'd like to have build: script, which generates production bundle, with specific .vue-components not being included in some cases. In other cases they should be included. Also, these components are stored in app itself - not in external library.
I've tried: to import .vue-components dynamically - let's say I have an array:
const customPreset = ['WidgetFirst', 'WidgetSecond', ...]
And empty object:
const widgets = {}
So I've tried to make something like this:
customPreset.forEach(v => { Object.assign(widgets, { [v]: () => import('./' + v + '.vue') }) })
export default widgets
Changing customPreset to some other array would allow to import another set of components...
But that doesn't work, because import() cannot operate with expressions.
So, what could be done to include various .vue-components into production bundle in various cases? Maybe it could be achieved through tweaking vue.config.js?
What you are looking for is lazy loaded components. In Vue they are available at multiple points.
In vue-router - you can import components per route, to load only when they are needed:
This is how to define an async component that will be automatically code-split by webpack:
const Foo = () => import('./Foo.vue')
You can also group components in the same chunk:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
Second option is Dynamic/Async components, which can be used in .vue files like this:
Vue.component(
'async-webpack-example',
// The `import` function returns a Promise.
() => import('./my-async-component')
)
It even support loading state, straight from the box:
const AsyncComponent = () => ({
// The component to load (should be a Promise)
component: import('./MyComponent.vue'),
// A component to use while the async component is loading
loading: LoadingComponent,
// A component to use if the load fails
error: ErrorComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout: 3000
})
I'm getting the following warning when an API request returns 401 and I send the user to the login screen:
Warning: Can't perform a React state update on an unmounted component.
What is the best way to handle this warning in a functional component that uses hooks. See the code below:
.
.
export default function MovieDetailsScreen() {
const [movie, setMovie] = useState({});
const movieId = useNavigationParam('movieId');
useEffect(() => {
// This is the method that does the request and returns 401 (It
// uses the fetch library)
Client.movies.show(movieId)
.then(result => {
setMovie(result)
})
}, [])
.
.
.
In general, warnings don't crash your application. But you should care about them. For instance, the previous warning(s) can lead to performance issues when not properly unmounting your stateful components
the request (e.g. Promise) isn't resolved yet, but you unmount the component. Then the request resolves, setMovie() is called to set the new state, but it hits an unmounted component.
You can try catch
Client.movies.show(movieId)
.then(result => {
setMovie(result)
})
.catch((err) => {
Client.movies.stop()
})
I am using asiox/vuejs to create a webpage. However I want to compartmentalize the code more. One example is I use axios to make requests to the backend, and the data in the response is commited into vuex.
this.$axios.get('events').then((response) => {
this.$store.commit('data/populate', response.data)
})
.catch((e) => {
console.error(e)
})
I want to write a util method for this, like this.$populate.events()
I have tried creating utils inside the plugins/ directory, but they dont have access to this.$axios or this.$store
Note that I have axios and vuex imported in nuxt.config.js
How can this be achieved?
If you need the function in the context, Vue instances and maybe even
in the Vuex store, you can use the inject function, which is the
second parameter of the plugins exported function.
Injecting content into Vue instances works similar to when doing this
in standard Vue apps. The $ will be prepended automatically to the
function.
Reference
export default ({ app, store }, inject) => {
inject("populate", () => {
app.$axios
.get("events")
.then(response => {
store.commit("data/populate", response.data);
})
.catch(e => {
console.error(e);
});
});
};
app variable is context property.
The root Vue instance options that includes all your plugins. For
example, when using axios, you can get access to $axios through
context.app.$axios.
Figured it out not 5 minutes after posting ...
Basically use this nuxt guide
And replace this with app in the method you'd like to move