I want to access my Vuex data in asyncData but I can't. Also I can't seem to be able to use axios module in asyncData.
I tried a lot.
pages/index.vue
export default {
asyncData() {
//in my project there's a lot more code here but i think this is enough
let id = this.$store.state.id //i know i should prob use getter but no
//here i want to do an axios req with this var "id" but axios doesnt work
return axios.get(`url${id}`)
.then(...) //not gonna write it out here
}
}
store/index.js
export const const = () => ({
id: "#5nkI12_fSDAol/_Qa?f"
})
I expect it to get the ID from Vuex and then do a Axios req. Whole app doesn't work.
The context provides additional objects/params from Nuxt to Vue
components. The context is available in special Nuxt lifecycle areas
like asyncData, fetch, plugins, middleware, modules, and
nuxtServerInit.
Reference
export default {
asyncData({ store }) {
const id = store.state.id
return axios.get(`url${id}`)
.then(...)
}
}
Related
I have a file where I keep all my functions that make api calls, then I import these functions inside components to use where needed. The issue I'm facing is that when api call is made and it returns 'unauthorized user'(because token has expired) I need to redirect users to the login page.
// apiCalls.js file
export async function getData(){
let response = await fetch(url)
let res = response.json()
// here I need to add redirect to /login if res.status.code is 401 for example
}
I tried to create a custom hook (with useNavigate) to use inside the function, but app throws error saying that hooks can't be used inside function. I can check status of the request inside the component(after I import function from apiCalls.js) but it doesn't seem like a correct way of approaching this as I'll have to add check inside every component that may use this function. Any advise is greatly appreciated
EDITED: to add context, I need to redirect user from a function( not functional component), function is exported from apiCalls.js file.
There's a great way to use hooks inside of a function - make the function a hook! The caveat is that this function will also need to follow the rules of hooks; a big one being the one you've just discovered: you should only be calling it inside a component or other hooks. If you're getting an error because of eslint, you generally also have to (and should) prefix this function with use (like useGetData).
export function useGetData(){
const navigation = useNavigation();
const getData = async (url) => {
let response = await fetch(url)
let res = response.json()
if (/* isInvalidStatus */) {
// navigate to '/login'
}
// return your data
}
return { getData }
}
export function MyComponent() {
const { getData } = useGetData();
// call getData() from useEffect or a click handler
// return jsx;
}
Brief explanation in case it helps:.
First we'll rename the function to follow convention, but we'll also have to remove the async keyword (which we address later). We'll add the useNavigation hook.
export function useGetData() {
// or whatever navigator your router provides
const navigation = useNavigation();
}
The hook itself can't be async, but we can expose a function in the hook's return object:
const getData = async (url) => {
// would probably use const instead of let
const response = await fetch(url);
if (response.status === 401 || response.status === 403) {
navigate('/login');
return;
}
return response.json();
}
return { getData }
And now in the component you can grab getData from useGetData and use it however you want; the auth guard logic will be handled for us in the hook, no matter which component we use it in.
Hooks are JavaScript functions, but you need to follow two rules when using them.
Don’t call Hooks inside loops, conditions, or nested functions.
Don’t call Hooks from regular JavaScript functions.
So if you want to use hook inside a function, change that function into hook
I'm trying to use getServerSideProps in my file [username].js (which uses dynamic routing). To use dynamic routing in next.js, you need to use the two functions getStaticPaths() and getStaticProps({ params }). However, you cannot use getServerSideProps with getStaticProps. This is a problem because I need to use getServerSideProps({ req, res }) to access headers containing important user info (such as req.headers['x-user-name']), and without that data I cannot properly add functionality to my application. What can I do here?
You don't need to use getStaticPaths and getStaticProps in a dynamic route file.
You can just use getServerSideProps and use the params object to get the username inside of it.
Example usage:
export async function getServerSideProps({ params, req }) {
let pageUserInDb = await User.findOne({ username: params.username }).populate('userRoles');
return {
props: {
pageUser: pageUserInDb
}
}
I have recently been trying to create a web app with NextJS. I know some basics in web development but I was a little lost when using NextJS as I didn't do any React either before.
I've tried fetching data from an API and using this data in my page. I struggled a bit but in the end I got it working with the help of getServerSideProps.
My question is, how could I use getServerSideProps multiple times in my application so that I can fetch many other routes ? I've tried using getServerSideProps in a different file, using its response in a function that I then export as a component and use it so I can "get components of getServerSideProps responses" if it makes sense, but had many different errors when trying to do so.
Could someone explain how it actually works and how I could resolve my issue, and if it doesn't work that way, how could I make it work?
Here's an example using Coinbase's API :
import { useState } from 'react'
import fetch from 'isomorphic-fetch'
export const getServerSideProps = async () => {
const res = await fetch('https://api.coinbase.com/v2/prices/ETH-USD/buy')
const data = await res.json()
return {
props: {
ethprice: data
}
}
};
I then use "ethprice" in my Home function such as :
export default function Home({ ethprice }) {
return (
[page content, divs, text etc...]
{etherprice.data.amount}
Thanks!
getServerSideProps is specific to that particular file, you can't just use it in any way you want.
const Example = (props) => {
return // this is your component
}
export const getStaticProps = async () => {
// this will provide props specifically for 'Example'
}
More than that getStaticProps will only be run once on static page generation and never again, along with fetching the props for that particular component only. So you can't get live data from it, only data required to generate the page (like page title).
You can have a look at getServerSideProps if you're looking for something more dynamic that can fetch props at runtime. After that you can pass those props down to children if you need to.
i use nextjs and i fetch some dummy data on home and now i want to make a page for each post that i got on home i made it but i feel is not a good code so if someone can healp me clear some things and also learn more on next i will appreciate this a lot. here is the code:
import { useRouter } from 'next/router'
import {useEffect} from 'react'
const post = () => {
const router = useRouter()
const pid = router.query.pid
async function getdata (){
if(pid){
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${pid}`)
const data = await res.json()
console.log(data)
}
}
useEffect(() => {
getdata()
}, [pid])
return(
<p>wasd{pid}</p>
)
}
export default post
I suppose you're talking about making components or each different route for each different data.
FIRST CASE-If we talk about the first case you can have a folder called components outside your pages for folder and make components there and map that component depending on your data or whatever.
SECOND CASE-If you want to have a different route [filename].js is the way to go this represents lets say localhost:3000/foldername/:filename. So you can do stuff from here. I'd suggest reading nextjs docs for more info on this routing.
We have a ReactNative app that uses redux, redux-persist and a HeadlessJS task. This task needs to have access to the store. As the task fires without booting the entire app (and so has no access by default), we thought we could simply create the store inside the task as well so that it would be rehydrated by redux-persist. It turns out, however, that the store created in this way is different from the one in the app: after running, they contain different values. We tested this in several ways and it seems indeed a problem with the stores (and not with the actions for instance)
How should we access a Redux store from an HeadlessJS task?
Relevant code:
store/configure.js:
configureStore = (client) => {
const middleware = createMiddleware(client);
const finalCreateStore = applyMiddleware(thunk, middleware, logger)(createStore);
const store = finalCreateStore(rootReducer, undefined, autoRehydrate());
return store;
};
In use (both in the app and in the service):
const client = new ApiClient();
const store = configureStore(client);
client.setStore(store);
persistStore(store, {
storage: AsyncStorage,
}
In the app we simply use the Provider from react-redux to use the store, in the service we use store.dispatch.
For people looking for solution. I have found the solution in here.
The idea is to bind the store to async method.
https://github.com/react-native-kit/react-native-track-player/issues/63
Copy pasting the solution here.
// index
const store = ...
....registerHeadlessTask('TrackPlayer', () => require('event-handler.js').bind(null, store));
// event-handler.js
module.exports = async (store, data) {
if(data.type == '...') {
store.dispatch(...);
}
};
simply create the store inside the task as well so that it would be rehydrated by redux-persist.
This did indeed happen.
You created two stores (not advisable with redux) which were both hydrate, but not linked, as there is no such thing as linked redux stores.
Every time you run createStore, it's a new store. And every time you dispatch, you do that on a specific store.
Unfortunately async or multithreaded issues are not directly addressed by redux.
It would be possible though with middleware and / or store listeners to keep the two stores in sync.
But redux is also just not a mean for communication between threads (which I assume these tasks are, or you could just give the task a reference to the store once it was created or give the main app the store reference from the task).
It's more a form of Command-Query-Separation and centralized state.
You can access your store directly as reference.
Let's say you have your headless set in index.js, then you can just simply use store there like this:
import { AppRegistry } from 'react-native';
import Store from './src/Redux/Store';
import { someAction } from './src/Redux/Actions/someActions';
import App from './App';
import { name as appName } from './app.json';
const HeadlessTask = async () => {
console.log('Receiving HeadlessTask');
const someParam = await Store.getState().Something.someParam;
if (someParam) {
Store.dispatch(someAction(someParam));
} else {
Store.dispatch(someAction());
}
};
AppRegistry.registerHeadlessTask('HeadlessTask', () => HeadlessTask);
AppRegistry.registerComponent(appName, () => App);