Verify whether an array is devoid of any elements, and prevent any pop-up from appearing if this condition is met

I am working on a map that displays 3 countries, each with a popup containing links and their respective names when clicked. However, I want to avoid showing the popup for countries that do not have any information in the "link" or "linkName" fields.

Can someone help me figure out how to check if the array is empty and prevent the popup from appearing for countries without any data in both the "link" and "linkName" fields?

The code snippet responsible for displaying the popup is shown below:

let polygonTemplate = series.mapPolygons.template;
    polygonTemplate.tooltipHTML = '<b>{country}</b>';
    polygonTemplate.events.on("hit", function (ev) {
      chart.closeAllPopups();
      // Map countries and link encoding
      const popupContent = `
        <strong>${ev.target.dataItem.dataContext.country}</strong><br />
        ${ev.target.dataItem.dataContext.link.map((url,urlIndex)=>`
        <a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
        `).join('')}
        `;
      chart.openPopup(popupContent);
    });

I attempted to use an if condition to handle this but it seems like something is not quite right. Here's the section of the code:

if (Array.isArray(ev.target.dataItem.dataContext.link) && !ev.target.dataItem.dataContext.link.length) {
      let polygonTemplate = series.mapPolygons.template;
        polygonTemplate.tooltipHTML = '<b>{country}</b>';
        polygonTemplate.events.on("hit", function (ev) {
        chart.closeAllPopups();
        // Map countries and link encoding
        const popupContent = `
        <strong>${ev.target.dataItem.dataContext.country}</strong><br />
        ${ev.target.dataItem.dataContext.link.map((url, urlIndex) => `
        <a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
        `).join('')}
        `;
        chart.openPopup(popupContent);
      });
    } else {
        console.log("something is wrong");
      }
    });

Note: The JavaScript code above is used for creating an interactive map using AmCharts library. Ensure you include all necessary dependencies and scripts for proper functionality.

Answer №1

Make the necessary adjustments in these lines:

popupContent = ev.target.dataItem.dataContext.link.map((url,urlIndex)=>
    `${(url.length) ? `<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>` : ''} `
).join('');
if (popupContent.trim().length != 0) {  // if popup contains something....
    popupContent = `<strong >${ev.target.dataItem.dataContext.country} </strong><br />`+ popupContent;
    chart.openPopup(popupContent);
}

The updated snippet is as follows:

am4core.ready(function () {

        // Themes begin
        am4core.useTheme(am4themes_animated);
        // Themes end

        // Create map instance
        let chart = am4core.create("map", am4maps.MapChart);

        // Responsiveness enabled
        chart.responsive.enabled = true;

        // Set map definition
        chart.geodata = am4geodata_worldHigh;

        // Set projection
        chart.projection = new am4maps.projections.Miller();

        // Zoom control
        chart.zoomControl = new am4maps.ZoomControl();

        let homeButton = new am4core.Button();
        homeButton.events.on("hit", function () {
            chart.goHome();
        });

        homeButton.icon = new am4core.Sprite();
        homeButton.padding(7, 5, 7, 5);
        homeButton.width = 30;
        homeButton.icon.path = "M16,8 L14,8 L14,16 L10,16 L10,10 L6,10 L6,16 L2,16 L2,8 L0,8 L8,0 L16,8 Z M16,8";
        homeButton.marginBottom = 10;
        homeButton.parent = chart.zoomControl;
        homeButton.insertBefore(chart.zoomControl.plusButton);

        // Center on the groups by default
        chart.homeZoomLevel = 3.5;
        chart.homeGeoPoint = {
            longitude: 10,
            latitude: 54
        };

        let groupData = [{
            "color": chart.colors.getIndex(0),
            "data": [{
                "country": "Germany",
                "id": "DE",
                "link": ["https://www.example1.com"],
                "linkName": ["Name 1"]
            }, {
                "country": "France",
                "id": "FR",
                "link": ["https://www.example2.com", "https://www.example3.com"],
                "linkName": ["Name 2", "Name 3"]
            }, {
                "country": "Belgium",
                "id": "BE",
                "link": [""],
                "linkName": [""]
            }]
        }];

        // This array will be populated with country IDs to exclude from the world series
        let excludedCountries = ["AQ"];

        // Create a series for each group, and populate the above array
        groupData.forEach(function (group) {
            let series = chart.series.push(new am4maps.MapPolygonSeries());
            series.name = group.name;
            series.useGeodata = true;
            let includedCountries = [];

            group.data.forEach(function (country) {
                includedCountries.push(country.id);
                excludedCountries.push(country.id);
            });

            let polygonTemplate = series.mapPolygons.template;
            polygonTemplate.tooltipHTML = '<b>{country}</b>';
            polygonTemplate.events.on("hit", function (ev) {
                chart.closeAllPopups();
                // Map countries and link encoding
                popupContent = ev.target.dataItem.dataContext.link.map((url,urlIndex)=>
                    `${(url.length) ? `<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>` : ''} `
).join('');
                if (popupContent.trim().length != 0) {
                    popupContent = `<strong >${ev.target.dataItem.dataContext.country} </strong><br />`+ popupContent;
                    chart.openPopup(popupContent);
                }
        });

        series.include = includedCountries;

        series.fill = am4core.color(group.color);
        series.setStateOnChildren = true;
        series.calculateVisualCenter = true;
        series.tooltip.label.interactionsEnabled = false; //disable tooltip click
        series.tooltip.keepTargetHover = true;


        // Country shape properties & behaviors
        let mapPolygonTemplate = series.mapPolygons.template;
        mapPolygonTemplate.fill = am4core.color("#c4a5e8");
        mapPolygonTemplate.fillOpacity = 0.8;
        mapPolygonTemplate.nonScalingStroke = true;
        mapPolygonTemplate.tooltipPosition = "fixed";

        mapPolygonTemplate.events.on("over", function (event) {
            series.mapPolygons.each(function (mapPolygon) {
                mapPolygon.isHover = false;
            })
            event.target.isHover = false;
            event.target.isHover = true;
        })

        mapPolygonTemplate.events.on("out", function (event) {
            series.mapPolygons.each(function (mapPolygon) {
                mapPolygon.isHover = false;
            })

        })

        // States
        let hoverState = mapPolygonTemplate.states.create("hover");
        hoverState.properties.fill = am4core.color("#FFCC00");

        series.data = JSON.parse(JSON.stringify(group.data));

    });

    // The rest of the world.
    let worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
    let worldSeriesName = "world";
    worldSeries.name = worldSeriesName;
    worldSeries.useGeodata = true;
    worldSeries.exclude = excludedCountries;
    worldSeries.fillOpacity = 0.5;
    worldSeries.hiddenInLegend = true;
    worldSeries.mapPolygons.template.nonScalingStroke = true;


});
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#map {
    width: 100%;
    height: 600px;
    overflow: hidden;
}

#map a,
b {
    cursor: pointer;
    color:  #003399;
    text-align: center;
}

#map a:hover {
    color: #023432;
}

.ampopup-content {
    /* width: 40%; */
    text-align: center;
}

.ampopup-header {
    background-color: #003399 !important;
}

.ampopup-close {
    filter: invert(1);
}

.ampopup-inside {
    background-color: rgb(255, 255, 255);
}

.ampopup-inside a {
    color: #28a86c !important;
}

.ampopup-inside a:hover {
    color: #023432 !important;
}

.ampopup-curtain {
    display: block !important;
    background-color: rgba(7, 22, 51, 0.7) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c7a5a8a8b3b4b3b5a6b787f2e9f7e9f7eaa5a2b3a6f6">[email protected]</a>/dist/css/bootstrap.min.css"></link>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfbdb0b0abacabadbeaf9feaf1eff1eff2bdbaabbeee">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/maps.js"></script>
<script src="https://cdn.amcharts.com/lib/4/geodata/worldHigh.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>

<div class="container">
    <div class="row">
        <div class="col-12">
            <div id="map"></div>
        </div>
    </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The modal disappears when the user clicks on the Previous/Next buttons of the jQuery UI datepicker

Using the jQuery datepicker from https://jqueryui.com/datepicker/ along with the UIkit framework found at I'm trying to incorporate the datepicker within a form that is inside a modal window. The issue arises when the modal window disappears after i ...

Swap the existing div with a fresh div using jQuery or JavaScript

Seeking a straightforward method to swap out a div with a different div, ensuring cross-browser compatibility with JavaScript or jQuery. Below is a code snippet to demonstrate. The goal is to replace "myDiv-B" with a new div: <div id="myDiv-C">{% in ...

JavaScript syntax issue detected, semicolon missing

I've encountered an issue with a form that contains potential errors defined in PHP. To dynamically change the form action based on the presence of errors, I have incorporated JavaScript into the process. The PHP error variable, $errors, has been conv ...

Increase the count if the item is already in the shopping cart - React

Is there a way to avoid adding the same product to the basket multiple times and instead just increment a counter? How can I effectively keep track of each item's count? this.state = { description: '', commaSalesPrice: '', ...

Challenges surrounding jQuery's .before

Currently, I am in the process of creating a simple carousel consisting of 4 divs. The carousel is utilizing 2 jQuery functions to position a div at either the first or last slot. The transitions being used are only alpha transitions as there is no need fo ...

Storing various data types like strings, integers, and booleans in a

I am new to programming and need help with inserting an array containing elements of different formats (such as date, float, and int) into a MySQL table in a database using Python. Please forgive any simple mistakes I may have made. Below is the code I ha ...

Create a new object by extracting JSON data using JavaScript

I am attempting to extract various data elements from a JSON file and place them into an object. My ultimate goal is to then convert this object back to JSON format, containing only the desired data. I believe that structuring the object like this might w ...

Filtering arrays within a dataframe using Scala in Spark

Hello, I am new to Scala and need some help. Currently, I have a dataframe that consists of two columns: The first column contains dates, and the second column is an array of words. created_at: string words: array element: string I am looking to on ...

Unable to adjust price slider on mobile device, bars are not sliding

I have been utilizing the jQuery slider from lugolabs.com for my website, and while it works flawlessly on desktop, it seems to have issues when viewed on mobile devices. You can check out the slider at this link: The library used for this slider is jQue ...

Click to expand for answers to commonly asked questions

Having trouble setting up a FAQs page on my blog and can't seem to get the code right. Check out what I'm trying to do here: http://jsfiddle.net/qwL33/ Everything seems fine but when I click on the first question, both questions open up. Can som ...

Having images that are too large in size and using a high percentage can

I'm encountering a strange issue. When I define the width and height of my images in pixels in my CSS file, all my jQuery animations and events work perfectly fine. However, when I switch to using percentages or 'auto' for the image dimensio ...

Is it beneficial to prioritize sorting using indexes?

Recently, I've been pondering over a new sorting algorithm that I think could potentially be more efficient, although I am uncertain about its effectiveness. 1) Let's consider an array 'a' consisting of solely positive numbers. 2 ...

Error Message for Sequelize Validation Fails to Appear as Expected

I am trying to implement Sequelize model validation in order to validate a form field. When the book or author fields are left empty, I want this message to be displayed: Oops! An error occurred. "Title" is required. "Author" is required. The issue I&ap ...

The compatibility between MUI Autocomplete and react-hook-form is limited and may not function properly

Problem Description I am encountering various errors at different times. Specifically, when I try to select a suggested option, I receive the following error and warning messages: Material-UI: The getOptionLabel method of Autocomplete returned undefined ...

What is the best way to handle waiting for an HTTP request to complete from a separate component?

https://i.sstatic.net/q4XYB.png An issue arises when calling the GetData function from a component's controller too early. I would like it to wait for the identification process to complete before triggering. During page loading, there is a server c ...

Node.js with Socket.io causes multiple events to be triggered

Currently, I am in the process of developing a rochambo game using node.js and socket.io. The game works as follows: A player places a bet, which is then sent to all other players. These players can choose a sign and click on 'challenge'. Howeve ...

The initial render of Keen-slider in NextJS can sometimes encounter difficulties when using server-side rendering

While incorporating the keen-slider library v5.4.0 into my nextJS project with TypeScript, I encountered a peculiar issue. The error arises when the keen-slider is initially loaded for the first time, resulting in mismatched transform types causing items ...

Steps for displaying a pop-up window and showcasing a JSF Response

In my current project, I am utilizing JSF 1.2 without any component libraries for a JSF Application. One specific scenario I am tackling involves having a JSF-rendered page where clicking on a link should trigger the opening of a pop-up page displaying d ...

JavaScript-powered dynamic dropdown form

I need help creating a dynamic drop-down form using JavaScript. The idea is to allow users to select the type of question they want to ask and then provide the necessary information based on their selection. For example, if they choose "Multiple Choice", t ...

Learn the way to extract an array from the appsettings.json file using .Net 6

I recently came across this amazing Stack Overflow thread about accessing the appsettings.json file in a .Net 6 console application. Interestingly, my own JSON file contains multiple arrays: "logFilePaths": [ "\\\\se ...