REST - create data with server side ID #2147
-
Bug report
Describe the expected behavior I have a standard REST pattern for my application, meaning that data is created on the client side, sent via POST request to the server, then stored and sent back by the server with the generated id. So my NOTES for example |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Hey @exinferis - thanks for filing this issue. I agree this can be a little fiddly with MST. At a high level, I think you can smooth things over by thinking about two distinct models in your MST codebase:
These two things can interact with one another, and you can model this whole flow through the ViewModel itself, but also handle actual server alongside. Here's how I would do this in my own app: import { types, getSnapshot, SnapshotOut, SnapshotIn } from "mobx-state-tree";
const Note = types.model("Note", {
id: types.identifierNumber,
title: types.string,
message: types.string,
date: types.string,
});
interface NoteSnapshot extends SnapshotIn<typeof Note> {}
type FormData = Omit<NoteSnapshot, "id">;
const FormViewModel = types
.model("FormViewModel", {
note: types.maybe(Note),
title: types.maybe(types.string),
message: types.maybe(types.string),
date: types.maybe(types.string),
})
.views((self) => ({
get formData(): FormData {
const { title, message, date } = self;
if (!title || !message || !date) {
throw new Error("Missing required fields");
}
return { title, message, date };
},
}))
.actions((self) => ({
createNote(id: number) {
const { formData } = self;
const note = Note.create({
...formData,
id,
});
self.note = note;
},
}));
let counter = 0;
async function server(snapshot: FormData): Promise<number> {
console.log("Received input", snapshot);
// Return an auto-incrementing integer as ID
counter += 1;
return counter;
}
(async () => {
// Instantiate the view model of your form. In practice, this would be part of a UI or other process
const noteForm = FormViewModel.create({
title: "Hello from MST",
message: "Hopefully this helps",
date: "2024-02-15",
});
// Send to the server and get an id
const id = await server(noteForm.formData);
noteForm.createNote(id);
const finalSnapshot = getSnapshot(noteForm);
console.log(JSON.stringify(finalSnapshot, null, 2));
})(); You can work with this code, fork it, etc. in CodeSandbox. Here's my thought process in designing this:
Let me know if that resolves your issue or not. Happy to talk further, but this is how I'd approach it. I'm sorry we don't have a ton of best practice guides for stuff like this. |
Beta Was this translation helpful? Give feedback.
-
Hey @exinferis - since I haven't heard back from you in a while, I'm going to convert this issue to a discussion and mark my answer as the correct one. That will close out the issue, and make it easier for folks to find this as an example if they need something similar. And of course, if my answer was insufficient, you can let me know and we can iterate in the discussions. Thanks! |
Beta Was this translation helpful? Give feedback.
Hey @exinferis - thanks for filing this issue. I agree this can be a little fiddly with MST. At a high level, I think you can smooth things over by thinking about two distinct models in your MST codebase:
These two things can interact with one another, and you can model this whole flow through the ViewModel itself, but also handle actual server alongside.
Here's how I would do this in my own app: