|
POST
|
I suppose there's some difference I can't explain, but here it is.
... View more
11-20-2023
09:18 AM
|
0
|
7
|
3526
|
|
POST
|
It seems that if you added an "after" function to your interceptor, you could use it to adjust the order as desired: esriConfig.request.interceptors.push({
urls: /\/query/,
before({ requestOptions }) {
if (/LIKE '[^%]/g.test(requestOptions.query?.where)) {
('like request intercepted', requestOptions);
requestOptions.query.where = requestOptions.query.where.replace(/ LIKE \'/g, ' LIKE \'%');
}
},
after: function(response) {
var notNulls = [];
var nulls = [];
response.data.features.forEach(function(feature) {
if (feature.attributes.KNOWNAS === null)
nulls.push(feature);
else
notNulls.push(feature);
});
response.data.features = notNulls.concat(nulls);
}
})
... View more
11-17-2023
12:08 PM
|
1
|
2
|
1685
|
|
POST
|
In that case, you'll need to use ESM syntax: import * as panel from "@arcgis/core/chunks/panel.js";
panel.P.prototype.renderHeaderNode = function() { return null; };
... View more
11-17-2023
09:53 AM
|
0
|
11
|
3570
|
|
POST
|
I don't think there's a documented way to do this. However, if the following executes prior to the creation of the Popup, it appears to achieve the desired results: require(["esri/chunks/panel"], function(panel) {
panel.Panel.prototype.renderHeaderNode = function() { return null; };
});
... View more
11-16-2023
04:43 PM
|
0
|
14
|
3616
|
|
POST
|
Thank you @Noah-Sager, I have found it to be fixed in 4.28. If you'd like a couple easy kills for the next release, these two are still open: Labeling bug with RangeDomain (4.26 and previous) Using selectedFeature when browsing cluster's features from popup Despite the name of that first one involving 4.26, it applies to 4.27 and 4.28 too.
... View more
11-16-2023
11:06 AM
|
1
|
0
|
5622
|
|
POST
|
The order of features displayed in the popup has produced no small amount of lively discussion. The popup does not show features in layer order, but rather in order of how quickly results are retrieved from the layers. Pretty much everything you'd ever want to know about it is in this thread, which although started back in 2014 continues to the present day. Despite the discussion being in a different context (ArcGIS Online), it's the very same issue.
... View more
11-15-2023
02:41 PM
|
1
|
2
|
2671
|
|
POST
|
Updated code and information below to correspond with recent changes in the SDK. Revised demonstration code since promiseUtils.create was removed in 4.27: require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/layers/support/LabelClass",
"esri/layers/support/RangeDomain",
"esri/core/promiseUtils",
"esri/Graphic",
"esri/geometry/Point",
"esri/rest/locator"
], (
Map,
MapView,
FeatureLayer,
LabelClass,
RangeDomain,
promiseUtils,
Graphic,
Point,
locator
) => {
var labelIndex = 1;
const view = new MapView({
map: new Map({
basemap: "gray-vector"
}),
container: "viewDiv",
extent: {
spatialReference: {
wkid: 102100
},
xmin: -14488954,
ymin: 3457304,
xmax: -10656095,
ymax: 5250211
},
popup: {
dockEnabled: true,
dockOptions: {
position: "top-right",
breakpoint: false
}
}
});
view
.when()
.then(fetchImages)
.then(getFeaturesFromPromises)
.then(createLayer)
.then(addToView)
.catch((e) => {
console.error("Creating FeatureLayer from photos failed", e);
});
/**
* Fetches a list of images and returns a list of promises
*/
function fetchImages() {
const numPhotos = 18;
const graphicPromises = [];
const baseUrl =
"https://arcgis.github.io/arcgis-samples-javascript/sample-data/featurelayer-collection/photo-";
for (let i = 1; i <= numPhotos; i++) {
const url = baseUrl + i.toString() + ".jpg";
const graphicPromise = exifToGraphic(url, i);
graphicPromises.push(graphicPromise);
}
return promiseUtils.eachAlways(graphicPromises);
}
// Filters only promises that resolve with valid values (a graphic
// in this case) and resolves them as an array of graphics.
// In other words, each attempt at fetching an image returns a promise.
// Images that fail to fetch will be filtered out of the response array
// so the images that successfully load can be added to the layer.
function getFeaturesFromPromises(eachAlwaysResponses) {
return eachAlwaysResponses
.filter((graphicPromise) => {
return graphicPromise.value;
})
.map((graphicPromise) => {
return graphicPromise.value;
});
}
// Creates a client-side FeatureLayer from an array of graphics
function createLayer(graphics) {
return new FeatureLayer({
source: graphics,
objectIdField: "OBJECTID",
fields: [
{
name: "OBJECTID",
type: "oid"
},
{
name: "url",
type: "string"
},
{
name: "labeltest",
type: "integer",
domain: RangeDomain.fromJSON({
type: "range",
name: "d_LABELTEST",
range: [1,10000000]
})
}
],
labelingInfo: [
LabelClass.fromJSON({
"labelPlacement": "esriServerPolygonPlacementAlwaysHorizontal",
"where": null,
"labelExpression": "[labeltest]",
"useCodedValues": true,
"symbol": {
"type": "esriTS",
"color": [
230,
76,
0,
255
],
"backgroundColor": null,
"borderLineColor": null,
"borderLineSize": null,
"verticalAlignment": "bottom",
"horizontalAlignment": "left",
"rightToLeft": false,
"angle": 0,
"xoffset": 0,
"yoffset": 0,
"kerning": true,
"haloColor": [
255,
255,
255,
178
],
"haloSize": 1.25,
"font": {
"family": "Arial",
"size": 16,
"style": "normal",
"weight": "bold",
"decoration": "none"
}
},
"minScale": 0,
"maxScale": 0
})
],
popupTemplate: {
title: (event) => {
return locator
.locationToAddress({
location: event.graphic.geometry
})
.then((response) => {
return response.address;
})
.catch((error) => {
return "The middle of nowhere";
});
},
content: "<img src='{url}'>"
},
renderer: {
type: "simple",
symbol: {
type: "text",
color: "#7A003C",
text: "\ue661",
font: {
size: 20,
family: "CalciteWebCoreIcons"
}
}
}
});
}
// Adds a given layer to the map in the view
function addToView(layer) {
view.map.add(layer);
}
/**
* Fetches and loads an image from a url and gets the latitude/longitude
* GPS data from the EXIF data of the image. Returns a promise that
* resolves to a Graphic with a point geometry representing the location
* where the photo was taken.
*/
function exifToGraphic(url, id) {
return new Promise((resolve, reject) => {
const image = document.createElement("img");
image.src=url;
image.onload = () => {
image.load = image.onerror = null;
EXIF.getData(image, function () {
const latitude = EXIF.getTag(this, "GPSLatitude");
const latitudeDirection = EXIF.getTag(this, "GPSLatitudeRef");
const longitude = EXIF.getTag(this, "GPSLongitude");
const longitudeDirection = EXIF.getTag(this, "GPSLongitudeRef");
if (!latitude || !longitude) {
reject(
new Error(
"Photo doesn't contain GPS information: ",
this.src
)
);
return;
}
const location = new Point({
latitude: dmsDD(latitude, latitudeDirection),
longitude: dmsDD(longitude, longitudeDirection)
});
resolve(
new Graphic({
geometry: location,
attributes: {
url: url,
OBJECTID: id,
labeltest: labelIndex++
}
})
);
});
};
image.onerror = () => {
image.load = image.onerror = null;
reject(new Error("Error while loading the image"));
};
});
}
// Converts a DMS coordinate to decimal degrees
function dmsDD([degrees, minutes, seconds], direction) {
let dd = degrees + minutes / 60 + seconds / 3600;
if (direction === "S" || direction === "W") {
dd *= -1;
}
return dd;
}
}); Despite changes being made to the offending function within labelFormatUtils.js in 4.28, the bug still remains. The problem occurs on line 15 below; instead of "return g.name" it should be "return a". function v(a, e) {
if (null == a)
return "";
const g = e.domain;
if (g)
if ("codedValue" === g.type || "coded-value" === g.type)
for (var f of g.codedValues) {
if (f.code === a)
return f.name
}
else if ("range" === g.type) {
const {max: h, min: b} = z.getDomainRange(e);
f = +a;
if (null != b && null != h && b <= f && f <= h)
return g.name
}
t.isDateField(e) ? a = r.formatDate(a, r.convertDateFormatToIntlOptions("short-date")) : t.isNumericField(e) && (a = y.formatNumber(+a));
return a || ""
}
... View more
11-15-2023
01:37 PM
|
0
|
0
|
1087
|
|
POST
|
It appears that adding the dojoConfig settings (particularly with the "packages" property set) prior to loading dojo resolves the problem: <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>DOJO and Esri javascript api 4.X</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
<script type="text/javascript">
window.dojoConfig = {
async: true,
cacheBust: "0.0.1",
has: {},
isDebug: true,
locale: "en-us",
parseOnLoad: false,
packages: [
{name:"esri", location:"https://js.arcgis.com/4.28/esri"}
]
};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.14.1/dojo/dojo.js"></script>
<script src="https://js.arcgis.com/4.28/"></script>
<script>
require([
"esri/layers/FeatureLayer",
"esri/rest/support/Query",
"esri/identity/IdentityManager",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function (FeatureLayer, Query, esriId, dom, on) {
var tokenStr = "63dJGeEz6333YPz6T07uLpGEbbVsnRPLqVVnEVkqhUq.";
var token = {
"server": "https://sampleserver6.arcgisonline.com/arcgis/rest/services",
"token": tokenStr
};
esriId.registerToken(token);
const countiesLayer = new FeatureLayer({
url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/3"
});
let queryCounties = countiesLayer.createQuery();
queryCounties.returnGeometry = false;
queryCounties.where = "state_name ='Washington'";
queryCounties.outFields = [ "OBJECTID", "state_name" ];
on(dom.byId("execute"), "click", execute);
function execute () {
countiesLayer.queryFeatures(queryCounties).then(function(response) {
document.write(response.features[0].attributes.state_name);
});
}
});
</script>
</head>
<body>
<input id="execute" type="button" value="Query County" />
</body>
</html>
... View more
11-02-2023
10:16 AM
|
1
|
1
|
3068
|
|
POST
|
If you're using 4.27 (and likely some prior versions), this would do it: div.esri-compass:hover {
background-color: #FF0000;
} However, due to the increased integration with Calcite and that this widget now uses a shadow DOM in 4.28, it's not possible to alter this property via a CSS selector.
... View more
10-26-2023
11:03 AM
|
0
|
1
|
1628
|
|
POST
|
As seen in the documentation for the visibilityExpression property, you cannot use this property to define your Arcade expression. Instead, it must reference a value in the expressionInfos collection, which is where your Arcade expression must go. There's an example nearly identical to what you're trying to do in the Form Constraint section of the Arcade reference page that will probably help.
... View more
10-26-2023
10:58 AM
|
0
|
0
|
920
|
|
POST
|
It is possible to do this if you don't mind using a bit of a hack to override the layer's createPopupTemplate method. If you replace the contents of the script tag starting on line 29 of the Intro to FeatureLayer Sample Sandbox with the code below, and click the Refresh button at the top right, you'll see it works as described: require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/core/reactiveUtils"
], (Map, MapView, FeatureLayer, reactiveUtils) => {
const map = new Map({
basemap: "hybrid"
});
const view = new MapView({
container: "viewDiv",
map: map,
popup: {
defaultPopupTemplateEnabled: true
},
extent: {
// autocasts as new Extent()
xmin: -9177811,
ymin: 4247000,
xmax: -9176791,
ymax: 4247784,
spatialReference: 102100
}
});
/********************
* Add feature layer
********************/
// Carbon storage of trees in Warren Wilson College.
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0"
});
featureLayer._esriCreatePopupTemplate = featureLayer.createPopupTemplate;
featureLayer.createPopupTemplate = function (options) {
var popupTemplate = this._esriCreatePopupTemplate(options);
popupTemplate.actions = [
{
title: "My Action",
id: "my-action",
className: "esri-icon-locate-circled"
}
];
return popupTemplate;
};
reactiveUtils.when(
() => view.popup?.actions,
() => {
view.popup.on("trigger-action", function (evt) {
alert(evt.action.title + " :: " + evt.action.id);
});
}
);
map.add(featureLayer);
}); The main part of this is seen on lines 36-48 above,
... View more
10-26-2023
10:47 AM
|
0
|
1
|
4818
|
|
POST
|
When using a GraphicsLayer, only the fonts listed in the Non-MapImageLayer fonts section are supported by default. Technically any font in pbf format is supported, but last I checked (which was awhile ago), there didn't seem to be a way to convert ttf fonts to pbf format. If there was such a way, that could solve the problem, since one could set up their own repository with their own pbf files. If you could find ttf versions of the fonts listed in the aforementioned section of the documentation, you could install them on the machine hosting ArcGIS Server, and they would then be supported both on client and server. Otherwise, yes, Arial is pretty much the only font supported by both the server and the JavaScript SDK.
... View more
10-20-2023
04:40 PM
|
0
|
1
|
1870
|
|
POST
|
The two tiling schemes are not the same, so there is not a one-to-one relationship between the tiles of each. As seen in the Known Limitations section of the TileLayer documentation, "All tiled layers [in the same map] must have the same tiling scheme and SpatialReference."
... View more
10-18-2023
10:44 AM
|
0
|
0
|
3013
|
|
POST
|
Is it really just one point, or a load of points stacked on one another? If it is just one point, I would recommend autogenerating the objectID values as in a previous response. As for the wrong location, it looks like it's treating your long/lat values as Web Mercator x/y values. You may have to project the coordinates into Web Mercator, which is easily done with webMercatorUtils.lngLatToXY and then use "x" and "y" properties instead of "latitude" and "longitude".
... View more
10-17-2023
02:27 PM
|
0
|
0
|
3031
|
|
POST
|
It was good to convert the lat and long to numbers as Rene suggested, but I see in your screenshot the "id" values are still strings. I've seen features not render in cases of duplicate or invalid objectid values, so you should probably convert those to integers as well, whether via Number or parseInt.
... View more
10-17-2023
01:59 PM
|
0
|
1
|
3041
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-19-2024 10:37 AM | |
| 1 | 03-31-2026 02:34 PM | |
| 1 | 12-09-2025 09:35 AM | |
| 2 | 12-09-2025 09:06 AM | |
| 1 | 11-26-2025 12:29 PM |