Help with function in JavaScript.

04-13-2021 01:30 PM
by Anonymous User
Not applicable

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">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <link rel="stylesheet" href="" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <!-- jQuery and JS bundle w/ Popper.js -->

    <script src="" crossorigin="anonymous"></script>
    <script src="" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="">
    <script src=""></script>
        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;
          text-overflow: ellipsis;
        .esri-item-gallery .esri-null-title {
          color: #999999;
        .action {
          color: blue;
          cursor: pointer;
          text-decoration: underline;



            ], 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.getCredential(info.portalUrl + "/sharing");
                .checkSignInStatus(info.portalUrl + "/sharing")
                .then(function (ev) {
                    console.log("logged in ");
                .catch(function (er) {

                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() {
                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(" user folder", folder.title);

        // Once portal is loaded, user signed in
        portal.load().then(function() {

            // 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


        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(){
        function createGallery(items) {
          function addLayer(){
            var htmlFragment = "";
            items.results.forEach(function(item) {          
                htmlFragment +=
                '<div class="esri-item-container">' +
                    ? '<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>') +
                    ? '<div class="esri-title">' + (item.title || "") + "</div>"
                    : '<div class="esri-title esri-null-title">Title not available</div>') +
                    ? '<div class="esri-title">' + (item.itemUrl || "") + "</div>"
                    : '<div class="esri-title esri-null-title">Title not available</div>') +
            function addLayer(){
            document.getElementById("itemGallery").innerHTML = htmlFragment;

    <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 id="personalizedPanel" style=" padding: 5px; text-align: center;">
      Welcome <span id="userId" style="font-weight: bold;"></span> &nbsp;-&nbsp;
      <span id="sign-out" class="action">Sign Out</span>
    <div id='mapDiv' style = "height: 400px; width: 800px">  </div>

    <div id="itemGallery" class="esri-item-gallery" style="width: 100%;"></div>



0 Kudos
5 Replies
Occasional Contributor II

Maybe because you have 2 'portal.load' references.

0 Kudos
Occasional Contributor II

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.  


0 Kudos
by Anonymous User
Not applicable

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. 



0 Kudos
Occasional Contributor II

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 ( === "satellite") {
    // The LayerView for the desired layer

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
var item = new PortalItem({
  id: "d7892b3c13b44391992ecd42bfa92d01"
if (item.isLayer) {
    portalItem: item

Sorry I can't help further.


0 Kudos
by Anonymous User
Not applicable

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. 

0 Kudos