This sample demonstrates how to add graphics to SketchLayer with the Sketch component in a 2D Map, edit their titles, and save the result as a WebMap.
SketchLayer stores sketches in a single graphics collection and serializes them as type-specific feature collections when saved in a web map.
How to use this sample
- Use the Sketch component in the top right to create a point, polyline, polygon, or text graphic.
- The Sketches panel lists each graphic. Select the Edit icon on a row to edit the graphic’s title, or the Delete icon to remove it. Text graphics display the same value as their title.
- Use the Sketch component to move or reshape selected graphics.
- Click Save WebMap to open the save dialog, enter a title, and save. The app displays a link to open the saved web map or an error message if saving fails.
How it works
Create the layer and map
Create a SketchLayer, add it to a WebMap, and assign the WebMap to the map component.
// Store each sketch in the SketchLayer and add that layer to the WebMap. const sketchLayer = new SketchLayer(); const webMap = new WebMap({ basemap: "gray-vector", layers: [sketchLayer], });
viewElement.map = webMap;Set up Sketch
Connect the Sketch component to the layer and enable point, line, polygon, and text tools. The component’s default symbols are used for the geometry tools; the sample customizes only the text symbol.
// Wait for Sketch to connect to the map before assigning its layer and tools. await sketch.componentOnReady();
sketch.layer = sketchLayer; sketch.availableCreateTools = ["point", "polyline", "polygon", "text"]; sketch.showCreateToolsText = true; sketch.textSymbol = new TextSymbol({ color: "#F94144FF", font: { family: "Arial Unicode MS", size: 20, }, haloColor: "#00000077", haloSize: 1, });Create graphics
Listen for Sketch’s create event to assign each new graphic a readable default title.
// Give each new graphic a useful title that will also appear in its popup or text symbol. sketch.addEventListener("arcgisCreate", ({ detail: event }) => { if (event.graphic && (event.state === "start" || event.state === "complete")) { if (!event.graphic.attributes?.title) { currentMapNoteNumber++; updateGraphicTitle(event.graphic, `Map Note ${currentMapNoteNumber}`); syncGraphicsList(); } } });Edit and delete graphics
The list is rebuilt from SketchLayer’s graphics collection. Each row has an Edit title action that reveals its input, and a Delete action that removes only that graphic. For text graphics, updating the title also updates the displayed text.
async function deleteGraphic(graphic) { // End an active edit first so Sketch does not retain a deleted graphic. const updateGraphics = Array.from(sketch.updateGraphics ?? []); if (updateGraphics.includes(graphic)) { await sketch.cancel(); } // Remove the graphic from the SketchLayer's graphics collection. sketchLayer.graphics.remove(graphic); }Save the WebMap
Click Save WebMap, enter a title, and save. The app synchronizes the view and creates a new WebMap with WebMap.saveAs(). The same dialog shows a link on success or an error message if saving fails.
// Save the current map as a new WebMap and show a link or an error in the dialog. saveWebMapButton.addEventListener("click", async () => { saveSuccessNotice.open = false; saveErrorNotice.open = false; saveWebMapButton.disabled = true; saveWebMapButton.textContent = "Saving..."; try { const title = webMapTitleInput.value || "SketchLayer WebMap"; await webMap.updateFrom(viewElement.view); const portalItem = new PortalItem({ title, }); const saveAsResult = await webMap.saveAs(portalItem);
saveSuccessLink.href = `${saveAsResult.portal.url}/home/item.html?id=${saveAsResult.id}`; saveSuccessLink.textContent = `Open ${saveAsResult.title ?? title}`; saveSuccessNotice.open = true; saveWebMapTitleLabel.hidden = true; saveWebMapButton.hidden = true; saveWebMapCancelButton.textContent = "Close"; } catch (error) { saveErrorMessage.textContent = error?.message ?? String(error); saveErrorNotice.open = true; } finally { saveWebMapButton.disabled = false; saveWebMapButton.textContent = "Save WebMap"; } });