How do I iterate over such object properties of an object in TypeScript?

I want to iterate over the oCities object and access the properties using a for…in loop as you can see in the attached screen recording but it looks like this for…in statement expected a string property for the iteration to occur, not an object. Any ideas on how I can pull this off?

type City = {
  iPopulation: number;
  sPopulation: string;
  latitude: number;
  longitude: number;
  color?: string;
  name: string;
  x: string;
  y: string;
};
interface Cities {
  [key: string]: City;
}
let oCities: Cities = {
  'Sao Paulo': {
    iPopulation: 11895893,
    sPopulation: '11,895,893',
    latitude: -23.5505,
    longitude: -46.6333,
    name: 'São Paulo',
    x: '0px',
    y: '0px',
  },
  'Rio de Janeiro': {
    iPopulation: 6453682,
    sPopulation: '6,453,682',
    latitude: -22.9068,
    longitude: -43.1729,
    name: 'Rio de Janeiro',
    x: '0px',
    y: '0px',
  },
  Salvador: {
    iPopulation: 2902927,
    sPopulation: '2,902,927',
    latitude: -12.9722,
    longitude: -38.5014,
    name: 'Salvador',
    x: '0px',
    y: '0px',
  },
  Brasilia: {
    iPopulation: 2852372,
    sPopulation: '2,852,372',
    latitude: -15.7942,
    longitude: -47.8822,
    name: 'Brasília',
    x: '0px',
    y: '0px',
  },
}

I’m trying to do something like:

  for(let city in oCities) {
    // save xy position
    oCities[city].x = oCities[city].longitude + 'lon';
    oCities[city].y = oCities[city].latitude + 'lat';
  }

But it’s not working. I really need some ideas.
enter image description here

Count numbers of Objects and Array contained into a main Object

I have an Object that contains various values, Objects, and Arrays, as shown in the snippet.

I am looking for a function that can count the total number of Objects and Arrays within this Object.

Currently, I am able to iterate through this main Object and log the Objects and Arrays with appropriate indentation. So, I can visualize the structure of this main Object later on; you don’t need to worry about that.

What I really want to understand is how my function works, specifically one particular line of code that I wrote. This line was suggested to me as a trick instead of simply calling the function again.

I will provide you with the Object and function in the snippet below, and I will indicate the part that I don’t fully comprehend afterwards.

        let datas = {
            name:"Main datas list",
            content:"List of Students and teachers",
            students:[
                {
                    name:"John",
                    age:23,
                    courses:["Mathematics","Computer sciences","Statistics"]
                },
                {
                    name:"William",
                    age:22,
                    courses:["Mathematics","Computer sciences","Statistics","Algorithms"]
                }
            ],
            teachers:[
                {
                    name:"Terry",
                    courses:["Mathematics","Physics"],
                }
            ]
        }

        function countAndDisplay(obj, indent = "") {
            let count = 0;

            for (let key in obj) {
                if (typeof obj[key] !== "object") {
                    console.log(`${indent}${key} : ${obj[key]}`);
                }

                if (typeof obj[key] === "object") {
                    if (Array.isArray(obj[key])) {
                        console.log(`${indent}Array : ${key} contains ${obj[key].length} element(s)`);
                    } else if (!Array.isArray(obj[key])) {
                        console.log(`${indent}Object : ${key} contains ${Object.keys(obj[key]).length} element(s)`);
                    }

                    count++; // Increment the count for each object or array encountered
                    
                    // Recursively count and display sub-elements

                    count += countAndDisplay(obj[key], indent + "  ");
                    
                    console.log(`${indent}=> DEBUG TEST COUNT VALUE = ${count}`); // just to understand how the itertion counts the elements
                }
            }

            return count;
        }

        let totalCount = countAndDisplay(datas);
        console.log(`datas contains ${totalCount} Objects or Arrays`);

Could you please explain the purpose and behavior of the code snippet here?

count++;
This line increments the value of the variable ‘count’ by 1 each time it is executed. I understand this part.

The next line is unclear to me.
count += the same function();
Specifically, I’m having trouble understanding how ‘count += the same function()’ can assign a value to the count variable immediately after it was incremented.

I don’t understand why the count variable is incremented (as if assigning a value to it), and then on the next line, count += is used with the recursive function (which seems to assign another value to the variable after the increment).

When I call the function, I know that it will execute all of its code again, including the line where I increment the count variable. However, the syntax is not easy to comprehend because if I simply call the function like countAndDisplay(obj[key], indent + " "); in place of count += countAndDisplay(obj[key], indent + " ");, it doesn’t work at all and doesn’t produce the expected result.

Could someone help me understand the logic behind this, so that I can improve my understanding and apply it in similar situations in the future? This isn’t an urgent matter, but rather an opportunity for me to enhance what I have already learned.

Thank you in advance for any time and effort you dedicate to answering this question.

How to use async properly to get chrome.storage?

I am creating a google chrome extension. On the popup, I am displaying a leaderboard. However, I am new to JavaScript so I don’t know how to properly use async. I am using chrome.storage to get stored scores to display on the leaderboard, then sending them from background.js to score.js. My issue is that, since chrome.storage.get happens asynchronously, my findScores method does not wait for chrome.storage.get to finish before incorrectly returning a default empty score.

Here is my code:

background.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      console.log(sender.tab ?
                  "from a content script:" + sender.tab.url :
                  "from the extension");
      if (request.type === "request") {
        var scoresVar = findScores(request.table, "All");
        console.log("Sending response " + scoresVar);
        sendResponse({scores: scoresVar})
      } 
      else if (request.type === "score") {
        saveScore(request.website, request.score, request.tab);
        sendResponse("Finished adding score " + request.score);
      }
    }
);

function findScores(table, website) {
    const categories = table.split("-");
    if (categories.includes("personal")) {
        chrome.storage.sync.get([website], function(response) {
            if (!(typeof response[website] === 'undefined')) {
                console.log("Found " + response[website]);
                return response[website];
            }
        });
    } else if (categories.includes("global")){
        // TODO: Add global leaderboards
        return ["-"];
    }
    console.log("Didn't find, on default");
    return ["-"];
}

popup.js

async function requestScores(tableID) {
  var url = "All"
  if (tableID.includes("current")) {
    var url = await getCurrentTab();
  }
  console.log("Sending message to load scores to " + url);
  (async () => {
    const response = await chrome.runtime.sendMessage({type: "request", request: "load scores", table: tableID, tab: url});
    console.log("Received: " + response);
    // add scores to HTML DOM
    });
  })();
}

My console messages reveal that I first return a default score, which is sent to popup.js. I have tried throwing async keywords in front of functions (as well as “await” in front of variables like scoresVar = await findScores(request.table, “All”) but it just caused more issues, where findScores still returned a default value, but background.j instead sent an undefined promise.

How can I fix my code?

How to Get an Integer from HTML in JavaScript [closed]

I’m trying to use JavaScript to get a number from my html using document.getElementById().value but I’m getting the whole thing (i.e 52 instead of just 52. Any tips on how to get this would be greatly appreciated

The only variations I know to try are adding .value at the end of the getElementById() or leaving it off

I just need to know how I can get the integer value of the element in the html instead of the whole tag.

How do I have buttons deselected upon page entry?

When I enter a page with filtered elements, all the elements are immediately displayed. I would like the reverse whereby on entry, you can’t see any of the filtered elements until the filter buttons are clicked. Can anyone help me with this?

Here is my code so far

filterSelection("all")
function filterSelection(c) {
  var x, i;
  x = document.getElementsByClassName("filterDiv");
  if (c == "all") c = "";
  // Add the "show" class (display:block) to the filtered elements, and remove the "show" class from the elements that are not selected
  for (i = 0; i < x.length; i++) {
    RemoveClass(x[i], "show");
    if (x[i].className.indexOf(c) > -1) AddClass(x[i], "show");

 
  }
}
// Show filtered elements
function AddClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    if (arr1.indexOf(arr2[i]) == -1) {
      element.className += " " + arr2[i];
    }
  }
}

// Hide elements that are not selected
function RemoveClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    while (arr1.indexOf(arr2[i]) > -1) {
      arr1.splice(arr1.indexOf(arr2[i]), 1);
    }
  }
  element.className = arr1.join(" ");
}

// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function() {
    var current = document.getElementsByClassName("active");
    current[0].className = current[0].className.replace(" active", "");
    this.className += " active";
  });
}

How to modify a regular expression to validate a text box with letters and numbers only, excluding certain characters like !@#$%^&*+=

Regular Expression for text box validation. I need to validate textbox. conditions like below

  • can enter numbers and letters.
  • need to avoid these characters !@#$%^&*+=

Currently i am using below regular expression. but it is not working.
<input type="text" pattern="^[w-.]+@([w-]+.)+[w-]{2,4}$" />

can u help me to find correct regular expression

How to use a sitemap to generate an accordion menu?

I use XHTML to author help documentation. The navigation menu is XML that’s transformed into JavaScript and then loaded/displayed in the HTML as a nav menu

    . This process creates generated content.

    I want to know how to use the generated JS in a webpage. Or, is there a way I can generate a menu using a sitemap perhaps?

    I’m good with HTML, CSS, and some JavaScript. I’m looking for some advice please.

    Jim

  • I’ve tried SmartMenus, but that’s not capturing the submenu items.

  • I’ve tried some simple JavaScript alternatives, and they aren’t working.

  • I’m not permitted to create an ID on the element. I can apply a class, though.

  • I’ve tried wrapping the ul in a div.

Pull data from an interactive map on a website

I want to get data on the number of Covid cases in LA County by Zip code (or the finest geographical unit the data could be).

On the website of the LA’s Public Health Department (http://dashboard.publichealth.lacounty.gov/covid19_surveillance_dashboard/), there is a map displaying the number of cases by city/community. I want to somehow pull and download this data as well as the geometry of the city/community to make the maps myself. However, I don’t know how to do this.

On the dropdown menu on the left there is a table data for the number of cases but I cannot get the geometry from these.

I have no experience with Javascript so I would appreciate any help or if anyone could point me to where to obtain similar data that would be really helpful too!

Application batches page not showing expected results when searching by batch number – how to fix?

I’m using Laravel Framework 6.20.44, PHP 7.2.25, and MySQL. The problem I’m facing is that when I perform a search using a batch number, the expected results are not displayed. Instead, it shows the same data that was initially displayed. Additionally, when I enter a search term that is not found in the database, the “No Data Found” message is not being shown.

//Here’s the route
Route::get(‘application_batches/index’, ‘ApplicationBatchController@searchBatchNum’);

//Here’s the index blade

@extends('layouts.app')
   @section('content')
    @if(session()->get('status'))
        <strong>{{ session('status') }}</strong>
        &times;
    @endif

    <div class="card">
        <div class='card-header text-center bg-primary text-white'>
            <h1>Visa Application Batches</h1>
        </div>

        <div class="col-md-8 offset-md-2">
            <input type="text" id="batchNum" name="batchNum" class="form-control text-center" 
                placeholder="Type batch number to search">
        </div>
        <button class="btn btn-primary">Search</button>

        <div id='application_list'>
            @include('application_batches.applicationBatch_list')
        </div>

        <table>
            <!-- table content -->
        </table>

        <div class="row">
            <div class="col-md-12 text-center">
                <a href="{{url('/')}}" class="btn btn-danger">Back</a>
            </div>
        </div>
    </div>
@endsection

@section('scripts')


function searchBatchNum(page) {
    $.ajax({
        url: "application_batches/index?page=" + page,
        data: { searchString: $('#batchNum').val() },
        success: function(data) {
            $('#index').html(data);
        }
    });
}

$(document).on('click', '.pagination a', function(event) {
    event.preventDefault();
    var page = $(this).attr('href').split('page=')[1];
    searchBatchNum(page);
});

$(document).on('keyup', '#batchNum', function() {
    searchBatchNum(1);
});
});

@endsection

//Here’s another blade named “applicationBatch_list”

<div class="table-responsive">
    <table class="table table-striped table-hover text-center" id="applicantIndex">
        <thead class="thead-dark">
            <tr>
                <th style="width:30%">Batch No</th>
                <th style="width:30%">Batch Date</th>
                <th style="width:30%">Status</th>
                <th style="width:10%"></th>
            </tr>
        </thead>
        <tbody>
            @if($application_batches->count() >0)
                @foreach($application_batches as $batch)
                    <tr>
                        <td>{{ $batch->batch_no }}</td>
                        <td>{{ $batch->batch_date }}</td>
                        <td>{{ $batch->receive_status }}</td>
                        <td><a href="{{ route('application_batches.edit', $batch->id) }}" class="btn btn-primary">View</a></td>
                    </tr>
                @endforeach
            @else
                <tr>
                    <td colspan="4" class="text-center font-weight-bold">No Data Found</td>
                </tr>
            @endif
        </tbody>
    </table>
    {!! $application_batches->links() !!}
</div>

//And finally the ApplicationBatchController

   class ApplicationBatchController extends Controller
{
/**
* Display a listing of the resource.
*
* @return IlluminateHttpResponse
*/
public function index()
{
if (Auth::user()->branch == 'MNL') {
$application_batches = DB::table('application_batches')
->leftJoin('applications', 'application_batches.batch_no', '=', 'applications.batch_no')
->where('applications.branch', 'MNL')
->orWhere('application_batches.status', '2')
->orWhere('application_batches.status', '3')
->orWhere('application_batches.status', '6')
->orWhere('application_batches.status', '7')
->orWhere('application_batches.status', '8')
->select('application_batches.id', 'application_batches.batch_no', 'application_batches.batch_date', 'application_batches.status', 'application_batches.total_applications')
->groupBy('application_batches.id', 'application_batches.batch_no', 'application_batches.batch_date', 'application_batches.status', 'application_batches.total_applications')
->orderBy('application_batches.batch_date', 'desc')->paginate(20);
} else {
$application_batches = DB::table('application_batches')
->leftJoin('applications', 'application_batches.batch_no', '=', 'applications.batch_no')
->where('applications.branch', Auth::user()->branch)
->select('application_batches.id', 'application_batches.batch_no', 'application_batches.batch_date', 'application_batches.status', 'application_batches.total_applications')
->groupBy('application_batches.id', 'application_batches.batch_no', 'application_batches.batch_date', 'application_batches.status', 'application_batches.total_applications')
->orderBy('application_batches.batch_date', 'desc')->paginate(20);
}

    $status_array = ApplicationBatchStatus::all();
    $status_list = array();

    foreach ($status_array as $status) {
        $status_list[$status->id] = $status->description;
    }

    foreach ($application_batches as $batch) {
        if ($batch->status == 2) {
            $batch->receive_status = $status_list[$batch->status] . " (" . $batch->total_applications . "/" . $batch->total_applications . ")";
        } else {
            $batch->receive_status = $status_list[$batch->status];
        }
    }

    return view('application_batches.index', compact('application_batches'));
}

public function searchBatchNum(Request $request)
{
    if ($request->ajax()) {
        $searchString = $request->get('searchString');

        if ($searchString != '') {
            $data = DB::table('application_batches')
                ->where(function($query) use ($searchString) {
                    $query->where('batch_no', 'LIKE', '%' . $searchString . '%')
                        ->orWhere('status', 'LIKE', '%' . $searchString . '%');
                })
                ->orderBy('id', 'desc')
                ->paginate(20);
        } else {
            $data = DB::table('application_batches')->orderBy('id', 'desc')->paginate(20);
        }

        return view('application_batches.applicationBatch_list', compact('data'))->render()->content();
    }
}
}

I want to display the searched data based on the batch number.

Socket.io client not connecting to the server

i’m using the Tampermonkey extension to run my socket.io client code and i do: window.socket = io(‘ws://127.0.0.1:3000’);

in the node js server i do

const { Server } = require("socket.io");
const io = new Server(3000, { /* options */ });

io.on('connection', function(socket) {
     console.log('connected');
});

it does not connect

Also loading socket.io on the tampermonkey extension:
// @require https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js

scrollTo and scrollIntoView don’t working

I’ve trying to apply a smooth scroll on my page when user click on nav menu (internal links).
I could create a link between the nav menu and the section on page and it works well, but when I try to apply the method scrollIntoView to make a smooth effect, this one doesn’t works. See my code below:

function initScrollSuave() {
  const linksInternos = document.querySelectorAll('.js-menu a[href^="#"]');

  function scrollToSection(event) {
    event.preventDefault();
    const href = event.currentTarget.getAttribute("href");
    const section = document.querySelector(href);

    section.scrollIntoView({
      block: "start",
      behavior: "smooth",
    });
  }

  linksInternos.forEach((link) => {
    link.addEventListener("Click", scrollToSection);
  });
}

initScrollSuave();

Someone could help me with it? I’ve tried to apply the scrollTo() but looks like it doesn’t work too.
I’m using Chrome browser.

function scrollToSection(event) {
    event.preventDefault();
    const href = event.currentTarget.getAttribute("href");
    const section = document.querySelector(href);
    const topo = section.offsetTop;

    window.scrollTo({
      top: topo,
      behavior: "smooth",
    });

    /*
    section.scrollIntoView({
      block: "start",
      behavior: "smooth",
    });*/
    
  }

  linksInternos.forEach((link) => {
    link.addEventListener("Click", scrollToSection);
  });
}

initScrollSuave();ype here

Collapsible Onclick function for PNG in HTML

I am trying to build a collapsible onclick function in HTML to display an image upon clicking a plus sign to fold out to a src image.
I have accomplished this, but need to program the function to collapse and close the image once I click onto the “-” sign.

Can someone please help me with this?

Thank you,
Mikey

<!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="styles.css"> </head> <body> <button id="testButton" onclick="myFunction()">+</button> <p id="demo"> </p> <script> function myFunction() { document.getElementById("demo").innerHTML = `<image style="width= 100%; height:auto" src="https://sharepoint2.web.PNG"/>`; document.querySelector('#testButton').innerHTML = '-'; } </script>

Unable to create connections between entities loaded from two JSON files using Cesium

I am currently working with Cesium and loading two JSON files as my data sources. The second JSON file contains entity 2 along with connection information, while the first JSON file only includes entity 1.

After loading both JSON files into Cesium using the Cesium.CzmlDataSource.load method, I can see both entity 1 and entity 2 displayed in the scene. However, the connection line between entity 1 and entity 2, which is specified in the second JSON file, is not being created or displayed.

I have verified that the connection information in the second JSON file is correct and includes the appropriate positions and properties for the connection line. Additionally, I have confirmed that both entity 1 and entity 2 are successfully loaded and accessible using the viewer.entities.getById method.

czmlDataSource = new Cesium.CzmlDataSource();
viewer.dataSources.add(czmlDataSource);
if (type == 1) {
  czmlDataSource.load("./SampleData/Test1012_3.json").then(function() {
    console.log("finalEntity", viewer.dataSources);
  });
}

In this code, I’m creating a new instance of Cesium.CzmlDataSource and adding it to the viewer.dataSources collection. Then, if the type variable is equal to 1, I’m loading the second JSON file using the load function of the czmlDataSource. The then function is used to execute the callback function once the loading is complete. In this example, I’m logging the viewer.dataSources collection to the console after the loading is finished.

enter image description here

I browse the connection records corresponding to the second data source and find that the _targetEntity of the first entity is undefined

enter image description here

I have attempted to load both JSON files into a single data source, but the connection line is still not being displayed. However, when I moved the information of the first entity to the second JSON file, the connection line appeared correctly.

How do I iterate over such object properties of an object in TypeScript/JavaScript?

I want to iterate over this oCities object below and access the properties using a for…in loop as you can see in the attached screenshot but it looks like this for…in statement expected a string property for the iteration to occur, not an object. Any ideas on how I can pull this off?

type City = {
  iPopulation: number;
  sPopulation: string;
  latitude: number;
  longitude: number;
  color?: string;
  name: string;
  x: string;
  y: string;
};
interface Cities {
  [key: string]: City;
}
let oCities: Cities = {
  'Sao Paulo': {
    iPopulation: 11895893,
    sPopulation: '11,895,893',
    latitude: -23.5505,
    longitude: -46.6333,
    name: 'São Paulo',
    x: '0px',
    y: '0px',
  },
  'Rio de Janeiro': {
    iPopulation: 6453682,
    sPopulation: '6,453,682',
    latitude: -22.9068,
    longitude: -43.1729,
    name: 'Rio de Janeiro',
    x: '0px',
    y: '0px',
  },
  Salvador: {
    iPopulation: 2902927,
    sPopulation: '2,902,927',
    latitude: -12.9722,
    longitude: -38.5014,
    name: 'Salvador',
    x: '0px',
    y: '0px',
  },
  Brasilia: {
    iPopulation: 2852372,
    sPopulation: '2,852,372',
    latitude: -15.7942,
    longitude: -47.8822,
    name: 'Brasília',
    x: '0px',
    y: '0px',
  },
}

enter image description here