noble-gold
noble-gold•14mo ago

Update auth

How to update details of a logged in user ? Is it possible to create a custom hook in auth provider ? Having the ability create a custom hook for an auth provider would be great. Currently, authProvider AuthBinding type doesnt have the option to plug in a custom hook. Adding more context, havin a hook to update any field of a logged in user will be great. Lets say allowing the user to change his username or any other field with a hook would be great. Currently, I can do so by getting the user from useGetIdentity hook. But as we are persisting the user in the local storage I would have to update the local storage as well outside of the auth provider. Not a hassle as I can just create a custom hook for it but having the ability to fix all this up directly inside a hook will clean be clean.
30 Replies
kapa.ai
kapa.ai•14mo ago
Hi @haribo_mushi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Hmm, I don't know enough to give you a confident answer yet. However, you can refer to the refine documentation for more information on authentication and auth providers: refine documentation (https://refine.dev/docs). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•14mo ago
<@886127984711438378> kapa.ai is still learning and improving, please let us how it did by reacting below
noble-gold
noble-gold•14mo ago
hey @kapa.ai I am adding deletebutton from refineantd to my show headerbutton props and after manually adding it, it fail to redirect me back to listing page. any ideao how to This wasnt the case when I didnt manually added DeleteButton in the headerbuttons prop. Any idea how to fix this ? I am guessing I have to passing it navigate function to its onSuccess props ?
kapa.ai
kapa.ai•14mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, you're on the right track. When you manually add the DeleteButton to the headerButtons prop, you might need to pass the onSuccess prop to handle the navigation after a successful delete action. You can use the useNavigation hook from refine to achieve this. Here's an example of how to add the DeleteButton with the onSuccess prop:
import {
Show,
ListButton,
EditButton,
DeleteButton,
RefreshButton,
useNavigation,
} from "@refinedev/antd";
import { Button } from "antd";

const PostShow: React.FC = () => {
const { navigate } = useNavigation();

return (
<Show
headerButtons={({
deleteButtonProps,
editButtonProps,
listButtonProps,
refreshButtonProps,
}) => (
<>
{listButtonProps && <ListButton {...listButtonProps} />}
{editButtonProps && <EditButton {...editButtonProps} />}
{deleteButtonProps && (
<DeleteButton
{...deleteButtonProps}
onSuccess={() => navigate("../")}
/>
)}
<RefreshButton {...refreshButtonProps} />
<Button type="primary">Custom Button</Button>
</>
)}
>
<p>Rest of your page here</p>
</Show>
);
};
import {
Show,
ListButton,
EditButton,
DeleteButton,
RefreshButton,
useNavigation,
} from "@refinedev/antd";
import { Button } from "antd";

const PostShow: React.FC = () => {
const { navigate } = useNavigation();

return (
<Show
headerButtons={({
deleteButtonProps,
editButtonProps,
listButtonProps,
refreshButtonProps,
}) => (
<>
{listButtonProps && <ListButton {...listButtonProps} />}
{editButtonProps && <EditButton {...editButtonProps} />}
{deleteButtonProps && (
<DeleteButton
{...deleteButtonProps}
onSuccess={() => navigate("../")}
/>
)}
<RefreshButton {...refreshButtonProps} />
<Button type="primary">Custom Button</Button>
</>
)}
>
<p>Rest of your page here</p>
</Show>
);
};
In this example, the onSuccess prop is passed to the DeleteButton, and it uses the navigate function from the useNavigation hook to navigate back to the listing page after a successful delete action. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•14mo ago
<@886127984711438378> kapa.ai is still learning and improving, please let us how it did by reacting below
noble-gold
noble-gold•14mo ago
@kapa.ai i am using mutateAsync from useCustomMutation query for my photo edit upload. I am setting my content-type header to be multipart/form-data. However, after putting this request the problem is for my next requests onward it keeps on setting my content-type to this instead of application/json. I did set my axios instance defaul header to be application/json but it seems to be getting ignored all over
kapa.ai
kapa.ai•14mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- It seems like the issue is related to the axios instance headers being overridden after setting the Content-Type to multipart/form-data. To fix this, you can create a new axios instance specifically for the file upload request, so it doesn't affect the default headers of your main axios instance. Here's an example of how to create a new axios instance for the file upload request:
import axios from "axios";

const fileUploadAxiosInstance = axios.create();

// Use the fileUploadAxiosInstance for your file upload request
const { mutateAsync } = useCustomMutation();

const handleFileUpload = async (file) => {
const formData = new FormData();
formData.append("file", file);

await mutateAsync({
config: {
headers: {
"Content-Type": "multipart/form-data",
},
},
// Use the new axios instance for the file upload request
axiosInstance: fileUploadAxiosInstance,
data: formData,
});
};
import axios from "axios";

const fileUploadAxiosInstance = axios.create();

// Use the fileUploadAxiosInstance for your file upload request
const { mutateAsync } = useCustomMutation();

const handleFileUpload = async (file) => {
const formData = new FormData();
formData.append("file", file);

await mutateAsync({
config: {
headers: {
"Content-Type": "multipart/form-data",
},
},
// Use the new axios instance for the file upload request
axiosInstance: fileUploadAxiosInstance,
data: formData,
});
};
By using a separate axios instance for the file upload request, you can ensure that the default headers of your main axios instance remain unchanged. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•14mo ago
<@886127984711438378> kapa.ai is still learning and improving, please let us how it did by reacting below
noble-gold
noble-gold•14mo ago
@kapa.ai is there not any other way around ?
kapa.ai
kapa.ai•14mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, there is another way to handle this issue without creating a separate axios instance. You can use an axios request interceptor to set the Content-Type header for specific requests and reset it back to application/json for other requests. Here's an example of how to use an axios request interceptor:
import axios from "axios";

const axiosInstance = axios.create();

axiosInstance.interceptors.request.use((config) => {
// Check if the request is for file upload
if (config.url && config.url.includes("/your-file-upload-endpoint")) {
config.headers["Content-Type"] = "multipart/form-data";
} else {
config.headers["Content-Type"] = "application/json";
}
return config;
});

// Use the axiosInstance for all your requests
import axios from "axios";

const axiosInstance = axios.create();

axiosInstance.interceptors.request.use((config) => {
// Check if the request is for file upload
if (config.url && config.url.includes("/your-file-upload-endpoint")) {
config.headers["Content-Type"] = "multipart/form-data";
} else {
config.headers["Content-Type"] = "application/json";
}
return config;
});

// Use the axiosInstance for all your requests
In this example, the interceptor checks if the request URL includes the file upload endpoint. If it does, it sets the Content-Type header to multipart/form-data. For all other requests, it sets the Content-Type header back to application/json. This way, you can ensure that the correct Content-Type header is set for each request without affecting the default headers of your main axios instance. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•14mo ago
<@886127984711438378> kapa.ai is still learning and improving, please let us how it did by reacting below
noble-gold
noble-gold•14mo ago
@kapa.ai
const config = {
"headers": {
"Content-Type": 'multipart/form-data;'
}
}

try {
const { data, } = await mutateAsync({
url: options?.action,
method: "patch",
config,
values: formData,
.............
const config = {
"headers": {
"Content-Type": 'multipart/form-data;'
}
}

try {
const { data, } = await mutateAsync({
url: options?.action,
method: "patch",
config,
values: formData,
.............
this is what it looks like it should only be setting on this one request but no. Why is such the case ?
kapa.ai
kapa.ai•14mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- It seems like you're trying to set the Content-Type header only for this specific request. However, it's not working as expected, and the header persists for other requests as well. The issue might be related to how you're passing the config object to the mutateAsync function. To ensure that the Content-Type header is set only for this specific request, you can try the following approach: 1. Make sure you're using the correct property name for passing the config object to the mutateAsync function. It should be axiosConfig instead of config. Here's the updated code snippet:
const config = {
headers: {
"Content-Type": "multipart/form-data;",
},
};

try {
const { data } = await mutateAsync({
url: options?.action,
method: "patch",
axiosConfig: config, // Use axiosConfig instead of config
values: formData,
});
// ...
}
const config = {
headers: {
"Content-Type": "multipart/form-data;",
},
};

try {
const { data } = await mutateAsync({
url: options?.action,
method: "patch",
axiosConfig: config, // Use axiosConfig instead of config
values: formData,
});
// ...
}
By using the correct property name axiosConfig, you should be able to set the Content-Type header only for this specific request without affecting other requests. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•14mo ago
<@886127984711438378> kapa.ai is still learning and improving, please let us how it did by reacting below
noble-gold
noble-gold•14mo ago
@kapa.ai 'axiosConfig' does not exist in type 'useCustomMutationParams<PutAvatarAdminResponse,
kapa.ai
kapa.ai•14mo ago
Let me check the knowledge base for you. One moment! :books: @haribo_mushi That's a great question, but unfortunately I am only capable of responding to a maximum of three questions per thread. Don't hesitate to create a new thread for any further questions you have though. I'm here to help!
apparent-cyan
apparent-cyan•14mo ago
if you want to sent mutation request to any api endpoint you can use this https://refine.dev/docs/api-reference/core/hooks/data/useCustomMutation/
noble-gold
noble-gold•14mo ago
i resolved this, I was using this hook. the hook is fine the issue was with the custom function that was defined inside the data provider. The boilerpate that is generated was overriding the defaults instead of just setting the headers for that one custom request any idea regarding the main question of this thread. Should I create a github issue for this. As of yet correct me I am wrong but there is no such hook from Auth provider which allows us to update the details of logged in user currently I just created a hook where I update the details of the logged in user which is stored in local storage
apparent-cyan
apparent-cyan•14mo ago
if you have feature request or, new feature idea please don't hesitate to open issue. we can discuss anything. but i'm not sure about this feature. is users has any diffrence from others resources ?
noble-gold
noble-gold•14mo ago
I mean for the auth. Like lets say if I want to update the email or age or any other attribute of a logged in user how can I do so ? just for that user which should only be done by that logged in user like u know we have useForgotPassword but that only works for password field what about other fields ?
apparent-cyan
apparent-cyan•14mo ago
you can add users resource and you can create your user update form anything you like
noble-gold
noble-gold•14mo ago
I mean I will then have to update logged in user as well separately wouldnt there be clash with useGetIdentity ? if I do it this way would the authProvider be in sync with the users resource ?
apparent-cyan
apparent-cyan•14mo ago
i believe it shouldn't be a problem. you can invalidate getUserIdentity query key after update user
noble-gold
noble-gold•14mo ago
oh got it but after invalidation does it ask me to login again ?
apparent-cyan
apparent-cyan•14mo ago
it's depends to your implementation. getUserIdentity just a interface. refine users provide this logic. in our examples it's just get data from API but if you think this feature is important. you can open feature request. with that other users and core members can see this too. i think users should be resource but i can be wrong
noble-gold
noble-gold•14mo ago
but if it is an application for just a logged in user then does it still makes sense to put it as a resource ? like how many users there are dont matter to me, if its just a user facing application and nothing to do with the other users I wont be doing any crud activity with the users resoruce except for editing him
apparent-cyan
apparent-cyan•14mo ago
yes, just don't implement list page. only edit
noble-gold
noble-gold•14mo ago
yeah thats fine too thanks for the help
apparent-cyan
apparent-cyan•14mo ago
thanks for the ideas
noble-gold
noble-gold•14mo ago
just wanted to add on my additonal thoughts, password is also just a field for user then why do we get a hook to update that ? If we can have a hook to update one of its field which in this case is password, then I think it would only make sense to offer a custom sort of hook where one can update another field of the auth 😅