Can I access flags added by package #nuxtjs/device from the store? - vue.js

I'm trying to initialize a store state variable with a flag generated by #nuxtjs/device:
export const state = () => ({
isMenuVisible: !$device.isMobile
});
This doesn't work though, I'm getting this error message:
$device is not defined
Any suggestion?

you missed 'this'
export const state = () => ({
isMenuVisible: !this.$device.isMobile
});

Related

make redux toolkit query inside useEffect

I am receiving a cat prop and want to fetch data from api whenever cat is changed using RTK query. But it's getting error the following error:
React Hook "useGetProductsQuery" cannot be called inside a callback".
How to make a RTK query whenever cat is changed?
const Products = ({cat,filter,sort}) => {
const [products, setproducts] = useState([])
const [filters, setFilters] = useState([])
useEffect(()=>{
const {data,isError,isLoading}=useGetProductsQuery()
console.log(data,isError,isLoading)
},[cat])
}
import { createApi, fetchBaseQuery }
from'#reduxjs/toolkit/query/react';
const baseUrl=process.env.REACT_APP_ECOMMERCE_API_URL
const createRequest = (url) => ({ url });
export const ecommApi = createApi({
reducerPath: 'ecommApi',
baseQuery: fetchBaseQuery({baseUrl}),
endpoints: (builder) => ({
getProducts: builder.query({
query: () => createRequest("/api/v1/products")
}),
})
})
export const{useGetProductsQuery}=ecommApi;
Why not just pass cat as an argument to the useQuery hook without the useEffect?
That will make a new request every time cat changes.
const {data,isError,isLoading}=useGetProductsQuery(cat)
As an addition to phry's answer:
If "cat" might be undefined use the skip parameter for conditional fetching:
const {data,isError,isLoading} = useGetProductsQuery(cat, {skip: !cat})
See https://redux-toolkit.js.org/rtk-query/usage/conditional-fetching

vuex base state is shared between modules

I am using multiple vuex modules in nuxt store and I want to use the same base state in multiple modules like this:
// ~/utils/Sharedstore.js
export default {
state: {
byId: {},
allIds: [],
}
},
// ~store/entities/myEntity.js
import SharedStore from '~/utils/SharedStore';
export const state = () => ({ ...SharedStore.state });
But it doesn't work, whenever i mutate one state the state of all modules will be changed.
When I do this for all my modules it works:
// ~store/entities/myEntity.js
export const state = () => ({
byId: {},
allIds: [],
});
Problem is I would like to have the duplicated base states in one place (SharedStore.state). Why does it not work when importing and how can I fix it?
I found a fix:
export const state = () => JSON.parse(JSON.stringify(ModelStore.state));
Need to deep clone the object using JSON.parse(JSON.stringify(obj)) instead of spreading.
I guess the contents of byId and allIds still get used by reference when spreading?

Code splitting with auto-registered dynamically imported Vue components

I am trying to use this techniqe. In short I am trying code splitting with auto-registered dynamically imported Vue components. My file structure is js/utils/vue.js and js/components/***.vue.
This is how my Vue components are loaded:
const files = require.context('../components', true, /\.vue$/i, 'lazy').keys();
files.forEach(file => {
Vue.component(file.split('/').pop().split('.')[0], () => import(`${file}`));
});
But it results in an error:
[Vue warn]: Failed to resolve async component: function () {
return webpack_require("./resources/js/utils lazy recursive ^.*$")("".concat(file));
}
Reason: Error: Cannot find module './MainNavbar.vue'
Manually registering the component, while still using dynamic import works.
Vue.component('main-navbar', () => import('../components/MainNavbar.vue'));
Why am I receiving this error?
edit:
I found something here that works for me:
const files = require.context('./', true, /\.vue$/i, 'lazy').keys();
files.forEach(file => {
Vue.component(file.split('/').pop().split('.')[0], () => import(`${file}`));
});
Judging from the error message, your expression () => import(${file}) needs to prepend the context path, since you're not referencing that like in () => import('../components/MainNavbar.vue')
so maybe something like
const componentName = key.split('/').pop().split('.')[0]
Vue.component(file.split('/').pop().split('.')[0], () => import(`../components/${file}`));
works?

AsyncStorage in redux thunk, action not dispatching

I am trying to use asynchStorage to dispatch actions when I recieve the data:
componentWillMount() {
AsyncStorage.getItem("loggedIn")
.then(this.props.dispatch(isLoadingCredentials(true)))
.then(
data =>
data
? this.props
.dispatch(setCredentials(JSON.parse(data)))
.then(this.props.dispatch(navigate("Month")))
.then(
this.props.dispatch(
isLoadingCredentials(false)
)
)
: this.props.dispatch(isLoadingCredentials(false))
);
}
Using redux connect
export default connect(mapStateToProps)(HomeScreen);
I get the error:
Possible Unhandled Promise Rejection (id: 0):
TypeError: _this2.props.dispatch(...).then is not a function
TypeError: _this2.props.dispatch(...).then is not a function
How can I dispatch actions when I receive the data?
Try defining mapDispatchToProps and passing it as a second argument, alongside mapStateToProps.
const mapDispatchToProps = dispatch => ({
isLoadingCredentials: (loadingCredentials) => (
dispatch(isLoadingCredentials(loadingCredentials))
)
})
You could use bindActionCreators as Pegase745 suggested. It's shorthand for the above.
Then pass it through to your component via connect.
connect(mapStateToProps, mapDispatchToProps)(HomeScreen)
You would then use your function like so, notice there's no dispatch property.
componentWillMount() {
AsyncStorage.getItem("loggedIn")
.then(() => this.props.isLoadingCredentials(true))
...
}
You probably want to refactor your call to AsyncStorage because you're calling isLoadingCredentials(true) once the Promise has been fulfilled.
componentWillMount() {
this.props.isLoadingCredentials(true);
AsyncStorage.getItem("loggedIn")
.then((user) => {
// You have your User, do as you wish
// Add setCredentials and others to mapDispatchToProps
})
.catch(() => {
this.props.isLoadingCredentials(false); // Error
});
}

I can't use Spread into mapStateToProps [React Native]

I got this error message
I know lots of questions are there on this error, but in my case, i can't use spread inside mapStateToProps, While in my previous case, I can use spread inside mapStateToProps. can anybody tell me about this error?
this is my code by the way
const mapStateToProps = state => {
const IncomeVal = _.map(state.IncomeVal, (val, uid) => {
return { ...val, uid };
});
return { IncomeVal };
};
export default connect(mapStateToProps, { ValueIncome })(PageHome);
Are you trying to return a props object with the same properties as the state.IncomeVal.val object and also a property for state.IncomeVal.uid? Please try this:
const mapStateToProps = state => ({
...state.IncomeVal.val,
uid: state.IncomeVal.uid
});
Here is a plunkr demonstrating the js spread operator.