I am using :slug instead of :id in the url and the value does not update when slug is in the query parameters.
This is the form(I am using react-hook-form):
<code>import {
useUpdateLogMutation,
useGetLogQuery
} from '../../../slices/logsApiSlice'
import { useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useForm } from 'react-hook-form'
const LogsEdit = () => {
const { slugLog } = useParams()
const { data: logData, isLoading, error, refetch } = useGetLogQuery(slugLog)
const [updateLog, { isLoading: loadingUpdate }] = useUpdateLogMutation()
useEffect(() => {
if (logData) {
setValue('title', logData.title)
}
}, [logData])
const {
register,
setValue,
handleSubmit,
formState: { errors }
} = useForm()
const onSubmit = async data => {
try {
const res = await updateLog({
...data,
slugLog: slugLog
}).unwrap()
refetch()
} catch (err) {
console.log(err)
}
}
return (
<>
{loadingUpdate && <p>loading</p>}
{isLoading ? (
<p>loading</p>
) : error ? (
<div>{error?.data?.message || error.error}</div>
) : (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor='title' name='title'>
Title
</label>
<input type='text' {...register('title')} />
<p>{errors.title?.message}</p>
<button type='submit'>Submit</button>
</form>
)}
</>
)
}
export default LogsEdit
</code>
<code>import {
useUpdateLogMutation,
useGetLogQuery
} from '../../../slices/logsApiSlice'
import { useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useForm } from 'react-hook-form'
const LogsEdit = () => {
const { slugLog } = useParams()
const { data: logData, isLoading, error, refetch } = useGetLogQuery(slugLog)
const [updateLog, { isLoading: loadingUpdate }] = useUpdateLogMutation()
useEffect(() => {
if (logData) {
setValue('title', logData.title)
}
}, [logData])
const {
register,
setValue,
handleSubmit,
formState: { errors }
} = useForm()
const onSubmit = async data => {
try {
const res = await updateLog({
...data,
slugLog: slugLog
}).unwrap()
refetch()
} catch (err) {
console.log(err)
}
}
return (
<>
{loadingUpdate && <p>loading</p>}
{isLoading ? (
<p>loading</p>
) : error ? (
<div>{error?.data?.message || error.error}</div>
) : (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor='title' name='title'>
Title
</label>
<input type='text' {...register('title')} />
<p>{errors.title?.message}</p>
<button type='submit'>Submit</button>
</form>
)}
</>
)
}
export default LogsEdit
</code>
import {
useUpdateLogMutation,
useGetLogQuery
} from '../../../slices/logsApiSlice'
import { useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useForm } from 'react-hook-form'
const LogsEdit = () => {
const { slugLog } = useParams()
const { data: logData, isLoading, error, refetch } = useGetLogQuery(slugLog)
const [updateLog, { isLoading: loadingUpdate }] = useUpdateLogMutation()
useEffect(() => {
if (logData) {
setValue('title', logData.title)
}
}, [logData])
const {
register,
setValue,
handleSubmit,
formState: { errors }
} = useForm()
const onSubmit = async data => {
try {
const res = await updateLog({
...data,
slugLog: slugLog
}).unwrap()
refetch()
} catch (err) {
console.log(err)
}
}
return (
<>
{loadingUpdate && <p>loading</p>}
{isLoading ? (
<p>loading</p>
) : error ? (
<div>{error?.data?.message || error.error}</div>
) : (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor='title' name='title'>
Title
</label>
<input type='text' {...register('title')} />
<p>{errors.title?.message}</p>
<button type='submit'>Submit</button>
</form>
)}
</>
)
}
export default LogsEdit
My model:
<code>import mongoose from 'mongoose';
import slug from 'mongoose-slug-updater';
const { Schema, model } = mongoose;
mongoose.plugin(slug);
const LogSchema = new Schema(
{
title: {
type: String,
unique: true,
},
slugLog: { type: String, slug: 'title', unique: true },
},
{ timestamps: true }
);
const Log = model('Log', LogSchema);
export default Log;
</code>
<code>import mongoose from 'mongoose';
import slug from 'mongoose-slug-updater';
const { Schema, model } = mongoose;
mongoose.plugin(slug);
const LogSchema = new Schema(
{
title: {
type: String,
unique: true,
},
slugLog: { type: String, slug: 'title', unique: true },
},
{ timestamps: true }
);
const Log = model('Log', LogSchema);
export default Log;
</code>
import mongoose from 'mongoose';
import slug from 'mongoose-slug-updater';
const { Schema, model } = mongoose;
mongoose.plugin(slug);
const LogSchema = new Schema(
{
title: {
type: String,
unique: true,
},
slugLog: { type: String, slug: 'title', unique: true },
},
{ timestamps: true }
);
const Log = model('Log', LogSchema);
export default Log;
The controller and route:
<code>const updateLog = asyncHandler(async (req, res) => {
const log = await Log.findOneAndUpdate(
{ slugLog: req.params.slugLog },
{ ...req.body },
{
new: true,
}
);
const updatedLog = await log.save();
if (updatedLog) {
res.status(200).json(updatedLog);
} else {
res.status(404);
throw new Error('Log not found');
}
});
</code>
<code>const updateLog = asyncHandler(async (req, res) => {
const log = await Log.findOneAndUpdate(
{ slugLog: req.params.slugLog },
{ ...req.body },
{
new: true,
}
);
const updatedLog = await log.save();
if (updatedLog) {
res.status(200).json(updatedLog);
} else {
res.status(404);
throw new Error('Log not found');
}
});
</code>
const updateLog = asyncHandler(async (req, res) => {
const log = await Log.findOneAndUpdate(
{ slugLog: req.params.slugLog },
{ ...req.body },
{
new: true,
}
);
const updatedLog = await log.save();
if (updatedLog) {
res.status(200).json(updatedLog);
} else {
res.status(404);
throw new Error('Log not found');
}
});
<code>router.route('/:slugLog').get(getLogBySlug).put(updateLog);
</code>
<code>router.route('/:slugLog').get(getLogBySlug).put(updateLog);
</code>
router.route('/:slugLog').get(getLogBySlug).put(updateLog);
Finally in the redux toolkit:
<code>updateLog: builder.mutation({
query: (data) => ({
url: `${LOGS_URL}/${data.slugLog}`,
method: 'PUT',
body: data,
}),
invalidatesTags: ['Logs'],
}),
</code>
<code>updateLog: builder.mutation({
query: (data) => ({
url: `${LOGS_URL}/${data.slugLog}`,
method: 'PUT',
body: data,
}),
invalidatesTags: ['Logs'],
}),
</code>
updateLog: builder.mutation({
query: (data) => ({
url: `${LOGS_URL}/${data.slugLog}`,
method: 'PUT',
body: data,
}),
invalidatesTags: ['Logs'],
}),
My workaround is to use /:id
routes for the PUT requests, but I would like to ask if I am misunderstanding something in the way data and queries work in the mutations and I do not need the extra routes.