Can someone help me with understanding why the addLayer() function is not working in my code. In the console it says it is not defined. JS API 4.18. I’m a bit new to JS and self-taught coder. So please bear with me.
I can only get it to work when the addLayer() is outside of the <script> tag that includes all the ESRI API stuff. I’ve tried to put it everywhere in those scripts tags, only works when it’s outside of it. The function will eventually include code from the API. *note that I just put the addLayer() function in numerous locations in the code.
What I’m trying to do is get users to be able to add their own content to the WebMap, then eventually print it out. Anyone else have any ideas how to do this. I know WAB builder has a nice widget that lets you add your content.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<!-- jQuery and JS bundle w/ Popper.js -->
<script src="https://kit.fontawesome.com/mmmmmm.js" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.18/"></script>
<style>
html,
body {
font-size: 14px;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.esri-item-gallery .esri-item-container {
float: left;
text-align: center;
padding: 10px;
width: 204px;
display: inline-block;
}
.esri-item-gallery .esri-item-container:hover {
}
.esri-item-gallery .esri-image {
width: 200px;
height: 133px;
border: 2px solid gray;
border-radius: 5px;
}
.esri-item-gallery .esri-null-image {
line-height: 133px;
text-align: center;
color: #999999;
}
.esri-item-gallery .esri-title {
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
}
.esri-item-gallery .esri-null-title {
color: #999999;
}
.action {
color: blue;
cursor: pointer;
text-decoration: underline;
}
</style>
<script>
require([
"esri/identity/OAuthInfo",
"esri/identity/IdentityManager",
"esri/WebMap",
"esri/config",
"esri/Map",
"esri/views/MapView",
"esri/widgets/LayerList",
"esri/layers/FeatureLayer",
"esri/geometry/Geometry",
"esri/portal/Portal",
"esri/portal/PortalQueryParams",
"esri/portal/PortalQueryResult"
], function (OAuthInfo, esriId, WebMap, esriConfig, Map, MapView, LayerList,FeatureLayer,Geometry,Portal, PortalQueryParams,PortalQueryResult) {
//AppID is populated
var info = new OAuthInfo({
appId: "..........",
portalUrl: "https://......./portal",
popup: false
});
esriId.registerOAuthInfos([info]);
esriId.getCredential(info.portalUrl + "/sharing");
esriId
.checkSignInStatus(info.portalUrl + "/sharing")
.then(function (ev) {
console.log(ev);
console.log("logged in ");
})
.catch(function (er) {
console.log(err)
});
document.getElementById("sign-in").addEventListener("click", function() {
// user will be redirected to OAuth Sign In page
esriId.getCredential(info.portalUrl + "/sharing");
});
document.getElementById("sign-out").addEventListener("click", function() {
esriId.destroyCredentials();
window.location.reload();
});
esriConfig.portalUrl = "https://....../portal";
portal = new Portal();
// Setting authMode to immediate signs the user in once loaded
portal.authMode = "immediate";
portal.load().then(function() {
// queryUsers
// This object autocasts as new PortalQueryParams()
var queryParameters = {
query: "username:" + portal.user.username
};
console.log(portal)
console.log(queryParameters)
portal.queryUsers(queryParameters).then(function(queryResults){
console.log(queryResults.results)
queryResults.results[0].fetchFolders().then(function(folders){
folders.forEach(function(folder){
console.log(" user folder", folder.title);
});
});
});
});
// Once portal is loaded, user signed in
portal.load().then(function() {
console.log(portal);
// Create query parameters for the portal search
// This object autocasts as new PortalQueryParams()
var queryParams = {
query: "type: 'Feature Service' & owner:" + portal.user.username,
sortField: "numViews",
sortOrder: "desc",
num: 20,
type: "Feature Service"
};
// Query the items based on the queryParams created from portal above
portal.queryItems(queryParams).then(createGallery);
console.log()
console.log(portal.queryItems(queryParams))
});
var map = new Map({
basemap: "topo-vector",
});
var view = new MapView({
container: "mapDiv", // Reference to the DOM node that will contain the view
map: map, // References the map object created in step 3
center : [-100, 38], // Sets the center point of the view at a specified lon/lat
zoom : 4, // Sets the zoom LOD to 13
});
function addLayer(){
console.log("Add")
}
function createGallery(items) {
function addLayer(){
console.log("Add")
}
var htmlFragment = "";
items.results.forEach(function(item) {
htmlFragment +=
'<div class="esri-item-container">' +
(item.thumbnailUrl
? '<a href=' + (item.itemUrl || "") + '><div href class="esri-image" style="background-image:url(' + item.thumbnailUrl + ');"></div></a><br><button class = "btn btn-info" onclick="addLayer()"><i class="fas fa-plus"></i></button>'
: '<div class="esri-image esri-null-image">Thumbnail not available</div>') +
(item.title
? '<div class="esri-title">' + (item.title || "") + "</div>"
: '<div class="esri-title esri-null-title">Title not available</div>') +
(item.title
? '<div class="esri-title">' + (item.itemUrl || "") + "</div>"
: '<div class="esri-title esri-null-title">Title not available</div>') +
"</div>";
});
function addLayer(){
console.log("Add")
}
document.getElementById("itemGallery").innerHTML = htmlFragment;
}
})
</script>
</head>
<body>
<div id="anonymousPanel" style="display:none; padding: 5px; text-align: center;">
<span id="sign-in" class="action">Sign In</span> and view your ArcGIS Online items.
</div>
<div id="personalizedPanel" style=" padding: 5px; text-align: center;">
Welcome <span id="userId" style="font-weight: bold;"></span> -
<span id="sign-out" class="action">Sign Out</span>
</div>
<div id='mapDiv' style = "height: 400px; width: 800px"> </div>
<div id="itemGallery" class="esri-item-gallery" style="width: 100%;"></div>
</body>
</html>
Maybe because you have 2 'portal.load' references.
Well, you also have 3 'addLayer' functions, 2 existing under the 'createGallery' function, and 1 existing at the main script level. But there's nothing calling an 'addLayer' function, nor is there anything in any of the 'addLayer' functions that's actually performing an addlayer on the map, just console.log references.
Thanks for the reply.
I have those function in there 3 x because I was just showing that I tried different locations.
Yeah I'm just trying to get the function to work before I work on the actual Add Layer functions.
error
I'm not familiar with the Portal object. I looked at the 4.18 version and it doesn't have much of an example. It seems you are doing what it says, initially, which is to create the Portal object, setup the query params and then run the query. Not sure where the map is getting set (if at all) in that example. In your code, after you create the Portal object and then set the query params and run the query, you then set up the Map and MapView. Nowhere do I see the creation of a Featurelayer or other object that you can add to the Map to create a layer. If the portal id that you obfuscated is supposed to be a Map with a Layer in it then I don't see a need to then create the Map and MapView.
Not sure if I can help you here, but to my previous points, there are 2 'portal.load' events that you should try to combine into 1 to see if that helps. And the 'addLayer' functions are just that, functions that need to be called, not events. If you are trying to get a reference to when the layer gets added, you may try something like:
// This function fires each time a layer view is created for a layer in
// the map of the view.
view.on("layerview-create", function(event) {
// The event contains the layer and its layer view that has just been
// created. Here we check for the creation of a layer view for a layer with
// a specific id, and log the layer view
if (event.layer.id === "satellite") {
// The LayerView for the desired layer
console.log(event.layerView);
}
});
But I don't really see anywhere that a layer is being added.
If the item being reference is a layer, you might try getting it as a PortalItem and then adding it to the map, as in:
// to access the portal item at this url
// http://www.arcgis.com/home/item.html?id=d7892b3c13b44391992ecd42bfa92d01
var item = new PortalItem({
id: "d7892b3c13b44391992ecd42bfa92d01"
});
if (item.isLayer) {
Layer.fromPortalItem({
portalItem: item
}).then(addLayerToMap);
}
Sorry I can't help further.
It's all good I really appericate the time you put into this.
But yeah I removed that second Portal Item.
I know how to create the Layer and add it to the map. It's not in the code I provided, It's just a simple console log. The key is to get that function to be added to each Portal Item (in for ForEach) button created when the createGallery function is triggered.