<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Create a FeatureLayer from a shapefile | Sample | ArcGIS Maps SDK for JavaScript</title>
<link rel="stylesheet" href="https://js.arcgis.com/5.0/esri/themes/light/main.css" />
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
const [Map, MapView, Expand, request, FeatureLayer, Field, Graphic] =
"@arcgis/core/views/MapView.js",
"@arcgis/core/widgets/Expand.js",
"@arcgis/core/request.js",
"@arcgis/core/layers/FeatureLayer.js",
"@arcgis/core/layers/support/Field.js",
"@arcgis/core/Graphic.js",
const portalUrl = "https://www.arcgis.com";
document.getElementById("uploadForm").addEventListener("change", (event) => {
const fileName = event.target.value.toLowerCase();
if (fileName.indexOf(".zip") !== -1) {
//is file a zip - if not notify user
generateFeatureCollection(fileName);
document.getElementById("upload-status").innerHTML =
'<p style="color:red">Add shapefile as .zip file</p>';
basemap: "dark-gray-vector",
const view = new MapView({
center: [-41.647, 36.41],
defaultPopupTemplateEnabled: true,
const fileForm = document.getElementById("mainWindow");
const expand = new Expand({
view.ui.add(expand, "top-right");
function generateFeatureCollection(fileName) {
let name = fileName.split(".");
// Chrome adds c:\fakepath to the value - we need to remove it
name = name[0].replace("c:\\fakepath\\", "");
document.getElementById("upload-status").innerHTML = "<b>Loading </b>" + name;
// define the input params for generate see the rest doc for details
// https://developers.arcgis.com/rest/users-groups-and-items/generate.htm
targetSR: view.spatialReference,
enforceInputFileSizeLimit: true,
enforceOutputJsonSizeLimit: true,
// generalize features to 10 meters for better performance
params.generalize = true;
params.maxAllowableOffset = 10;
params.reducePrecision = true;
params.numberOfDigitsAfterDecimal = 0;
publishParameters: JSON.stringify(params),
// use the REST generate operation to generate a feature collection from the zipped shapefile
request(portalUrl + "/sharing/rest/content/features/generate", {
body: document.getElementById("uploadForm"),
const layerName = response.data.featureCollection.layers[0].layerDefinition.name;
document.getElementById("upload-status").innerHTML = "<b>Loaded: </b>" + layerName;
addShapefileToMap(response.data.featureCollection);
function errorHandler(error) {
document.getElementById("upload-status").innerHTML =
"<p style='color:red;max-width: 500px;'>" + error.message + "</p>";
function addShapefileToMap(featureCollection) {
// add the shapefile to the map and zoom to the feature collection extent
// if you want to persist the feature collection when you reload browser, you could store the
// collection in local storage by serializing the layer using featureLayer.toJson()
// see the 'Feature Collection in Local Storage' sample for an example of how to work with local storage
const layers = featureCollection.layers.map((layer) => {
const graphics = layer.featureSet.features.map((feature) => {
return Graphic.fromJSON(feature);
sourceGraphics = sourceGraphics.concat(graphics);
const featureLayer = new FeatureLayer({
fields: layer.layerDefinition.fields.map((field) => {
return Field.fromJSON(field);
// associate the feature with the popup on click to enable highlight and zoom to
view.goTo(sourceGraphics).catch((error) => {
if (error.name != "AbortError") {
document.getElementById("upload-status").textContent = "";
<div style="padding-left: 4px">
<a href="https://bsvensson.github.io/various-tests/shp/drp_county_boundary.zip"
<p>Add a zipped shapefile to the map.</p>
href="https://doc.arcgis.com/en/arcgis-online/reference/shapefiles.htm"
help topic for information and limitations.
<form enctype="multipart/form-data" method="post" id="uploadForm">
<label class="file-upload">
<span><strong>Add File</strong></span>
<input type="file" name="file" id="inFile" />
<span class="file-upload-status" style="opacity: 1" id="upload-status"></span>
<div id="fileInfo"></div>