Hi!
i am trying to add a page to the global menu after its being created so far i have managed to replace the menu.
This is my current code run in page afterchange hook:
import payload from "payload";
export const addPageToMenu = async (args) => {
if (args.operation === "create" {
let menu = await payload.findGlobal({ slug: "mainMenu" });
if (args.doc) {
await payload.updateGlobal({
slug: "mainMenu",
data: {
items: [
{
type: "link",
label: args.doc.title,
link: {
type: "reference",
reference: {
value: args.doc.id,
relationTo: "pages",
},
},
subMenu: { blocks: 0 },
},
...menu.items.map((item) => {
return {
link: {
...item.link,
reference: {
...item.link.reference,
value: {
...item.link.reference.value,
layout: {
...item.link.reference.value.layout,
},
},
},
},
...item,
};
}),
],
},
});
return args.doc;
}
}
return args.doc;
};
this create a new entry but the old entries loses connection is there a way to just use the ids instead of passing the whole referenced document? i.e
{
"items": [
{
"link": {
"reference": "id of document"
}
}
]
}
Solution hook for adding page when created and deleting when page is deleted.
import payload from "payload";
import { FieldHookArgs } from "payload/dist/fields/config/types";
import { MainMenu, Page } from "../../payload-types";
/**
* fetches the main menu from the database
*/
const fetchMenu = async (): Promise<MainMenu> =>
await payload.findGlobal({ slug: "mainMenu" });
/**
* fetch the menu, add the new page to it, and then update the menu
* @param args - {
* @returns The page that was created.
*/
export const addPageToMenu = async (args: {
doc: Page;
operation: FieldHookArgs["operation"];
}) => {
const menu = await fetchMenu();
if (args.operation === "create") {
const newArray = menu.items.map((item) => {
return {
...item,
link: {
...item.link,
reference: {
value:
typeof item.link.reference.value !== "string" &&
item.link.reference.value.id,
relationTo: item.link.reference.relationTo,
},
},
};
});
if (args.doc && menu) {
await payload.updateGlobal({
slug: "mainMenu",
data: {
items: [
...newArray,
{
type: "link",
label: args.doc.title,
link: {
type: "reference",
reference: {
value: args.doc.id,
relationTo: "pages",
},
},
subMenu: { blocks: 0 },
},
],
},
});
return args.doc;
}
}
};
/**
* fetches the menu, filters out the item with the id that matches the id passed in as an argument,
* and then updates the menu with the filtered array
* @param args - { id: string }
* @returns The return type is a Promise<void>
*/
export const deleteMenu = async (args: { id: string }) => {
const menu = await fetchMenu();
const deleteArray = menu.items.filter(
(element) =>
typeof element !== "string" &&
typeof element.link.reference.value !== "string" &&
element.link.reference.value.id !== args.id
);
await payload.updateGlobal({
slug: "mainMenu",
data: {
items: [
...deleteArray.map((item) => {
return {
...item,
link: {
...item.link,
reference: {
value:
typeof item.link.reference.value !== "string" &&
item.link.reference.value.id,
relationTo: item.link.reference.relationTo,
},
},
};
}),
],
},
});
return;
};
Hi!
I figured it out, the solution is in my question. Just have to pass the id as value instead of the whole object.
i dont know why i didnt try that first even tho that was how i wanted it to work..
welp will leave this here. Maybe helps someone else 👍🏿
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.