THREE.JS Object3D.removeFromParent is not a function error when removing childs of scene.children in forEach loop

I’m trying to delete temporary THREE.JS 3Dobjects in forEach loop. My code is doing the job but I’ve got “Object3D.removeFromParent is not a function” error in console while I’m doing that.

I’m working on app that shows two views at once in different mode so this.scenes = [scene1, scene2] and I’m using Potree to generate pointclouds that’s why my scene have it’s own scene inside.

That’s the code:

    clearTemp() {
      this.scenes.forEach((scene) => {
        scene.scene.children.forEach((child) => {
          if (child.name.includes("temp")) {
            this.#removeObject3D(child)
          }
        })
      })
    }

    #removeObject3D(obj) {
      if (!(obj instanceof THREE.Object3D)) return false;

      if (obj.geometry) obj.geometry.dispose();
  
      if (obj.material) {
          if (obj.material instanceof Array) {
              obj.material.forEach(material => material.dispose());
          } else {
              obj.material.dispose();
          }
      }
      obj.removeFromParent();
      return true;
    }

I’ve tried to use Object3D.remove() function like so:

clearTemp() {
      this.scenes.forEach((scene) => {
        scene.scene.children.forEach((child) => {
          if (child.name.includes("temp")) {
            scene.scene.remove(child)
          }
        })
      })
    }

While doing this that way, there are no errors but it doesn’t remove temp objects as expected.

How to do it properly, remove all temp objects and get rid of that error message?

Script in html file is loading too fast? [duplicate]

I have a question about a script that I have which applies new changes to the style of other div elements on my webpage.

This script must be loaded within the <head> and must be applied after all other scripts have been loaded.
Now, for some reason sometimes changes are being applied through this script and sometimes not.

It is very strange, but when I look within the network tab here are differences when changes apply and weren’t applied:

CHANGES ARE BEING APPLIED WHEN THERE IS A GAP?

GAP

CHANGES ARE NOT BEING APPLIED WHEN THERE IS NO GAP?

NO GAP

Can anyone tell me what is happening here, because I’m kind of lost here…

I tried using defer/async attributes on the script, i tried to delay the script with setTimeout, i tried to use document.addEventListener(DOMContentLoaded) as well as window.addEventListener(load).. none of these will work…

Reminder:
this questions has nothing to do with adding script after page load, there is a problem in my situation. Somehow, after my script runs sometimes when there is a gap (some execution time?) then changes are being applied. When there is no execution time/no gap (i’m not sure exactly how this is happening) but then changes are not being applied.

Javascript Fetch value cannot be used [duplicate]

I am trying to fetch a string from an api, i console.log before return, it is the word I need and it is a string, but my ‘const wordineed = async1()’ is not a string, what did I miss?

const async1 = async ()=>{
    try {
        const response = await fetch(url, options);
        const result = await response.text();
        console.log(result.toUpperCase());
        console.log(typeof(result.toUpperCase()))
        return result.toUpperCase()
       
    } catch (error) {
        console.error(error);
    }
    }

const wordineed = async1()

I am expecting to get a string that can be used from the function async1()

Script isnt working properly after switching Form into ModelForm in django

In my django app I have changed my form for series discharge from forms.Form in forms.ModelForm and form itself is working properly. However, on that same form I have a button that would take remaining quantity of specific series that’s being discarged and put that value into quantity input field. Before my form in forms.py was described like this:

class DischargeForm(forms.Form):
    quantity = forms.DecimalField(
        label="Quantity to be discharged:", 
        min_value=1, 
        widget=forms.NumberInput(attrs={
            "class": "form-control", 
            "style": "width: 300px;"
        });

Now it looks like this:

class DischargeForm(forms.ModelForm):
    class Meta: 
        model = Discharge
        fields = ['quantity',]
        widgets = {
            'quantity': forms.NumberInput(attrs={"class": "form-control", "style": "width: 300px;"}
        ),
        labels= {"quantity": "Quantity to be discharged:",}

My script that enables the button functionality looks like this:

<script>
  document.addEventListener("DOMContentLoaded", function () {
    const inputQuantityButton = document.getElementById("input-quantity");
    inputQuantityButton.addEventListener("click", function(){
    event.preventDefault();
    const remainingQuantity = {{ series.quantity }};
    document.getElementById("id_quantity").value = remainingQuantity;
    });
  });
</script>

Form with button on html page looks like this:

<form method="post" id="discharge-form">
{% csrf_token %}
{{ form.as_p }}
   <button id="input-quantity">Remaining quantity</button>
   <button type="submit">Discharge</button>
</form>

For some reason that button isn’t working properly. When button is clicked form just gets sent as if submit button was clicked ( event.preventDefault(); isn’t working?). I have inspected the html code django generates and id of input field realy is id="id_quantity". Im losing my mind over this. Models and views remained the same and everything was working as it was suposed to untill I made that change.

Endless ticker css

Please tell me, is it possible to make an endless running line (css or js) in which you won’t have to wait until the line ends and starts again, and the words will always follow each other?

div {
  width: 200px;
}
<div>
<marquee direction="right" scrollamount="10">STRING</marquee>
</div>

SVG.js version 3.0.5 – Animate a rectangle to move along a specified path

I have come across a working example of using SVG.js version 2.5.0 for moving a rectangle along a path in jsfiddle. I am trying to duplicate the same behavior but in SVG.js version 3.0.5 but keep getting back an error.

The jsfiddle resides at : jsfiddle and my attempt is at : jsfiddle

When the code is run in chrome i get the following error in the console :

sugar.js:125 Uncaught TypeError: Failed to execute 'getPointAtLength' on 'SVGGeometryElement': The provided float value is non-finite.
    at Path.pointAt (sugar.js:125:32)
    at o.<anonymous> (svgjsVersion3.html:24:34)
    at o.value (Runner.js:430:38)
    at o.value (Runner.js:305:28)
    at n.value (Timeline.js:274:29)
    at _draw (Animator.js:86:17)

The complete html of the page that i am running is :

<html>
    <head>
        <title>SVG.js</title>
        <style>
            html, body, #drawing{
                width:100%;
                height:100%;
            }      
        </style>
        <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/[email protected]/dist/svg.min.js"></script>
    </head>
    <body onload="onload();">
        <div id="drawing"></div>
        <script>
            function onload() {
                var draw = SVG().addTo('#drawing').size(800, 800);
                var rect = draw.rect(100, 100).attr({fill: '#f06'});
                var path = draw.path("m 357.64532,453.84097 c 17.62007,8.02216 -2.12058,27.70935 -13.33334,29.28571 -30.3859,4.27185 -48.34602,-29.97426 -45.23807,-55.9524 5.5594,-46.46879 56.1311,-70.59787 98.57145,-61.19043 62.28294,13.8058 93.32728,82.57702 77.1428,141.19051 C 453.21679,585.29693 365.67122,623.42358 290.97859,600.26951 196.98554,571.13248 151.71003,464.56996 181.93108,373.84089 218.53281,263.95583 344.23687,211.49702 450.97875,248.84102 576.77037,292.84963 636.43303,437.76771 591.93099,560.50775 540.55162,702.21597 376.3736,769.09583 237.6452,717.41234 80.01319,658.68628 5.9069261,475.21736 64.788247,320.50751 130.84419,146.94643 333.62587,65.607117 504.31214,131.69819 693.80625,205.0718 782.38357,427.18225 709.07382,613.84113");
                var length = path.length();
                path.fill('none').stroke({width: 1, color: '#ccc'});
                
                rect.animate(8000, '<>').during(function(pos, morph, eased){
                    var p = path.pointAt(eased * length)
                    rect.center(p.x, p.y)
                }).loop(true, true)            
            }
        </script>
    </body>
</html>

Problem with Ball Collision Detection Issues with Clipping in Javascript Canvas

I’ve been struggling to debug the collision detection in my JavaScript animation code for a while now. I’m facing a problem where some balls are clipping through each other, while others are sticking together. Here’s a live demo of the code: JsFiddle

In the code, I’m trying to simulate the motion of multiple balls in a canvas, with collision detection and bouncing off walls and other balls. However, there seems to be an issue with the collision logic and ball behavior that I can’t quite pinpoint. Any help or suggestions on how to fix this issue would be greatly appreciated.

window.addEventListener('resize', resizeCanvas, false);
canvas.style.background="black";
const ctx=canvas.getContext("2d");
canvas.width =window.innerWidth;
canvas.height = window.innerHeight    ;
let isPaused=false;

function resizeCanvas(){
    canvas.width =window.innerWidth;
    canvas.height = window.innerHeight;
   
}
let balls=[];

function Ball(x,y,radius,color,vx,vy)
{
    this.x=x;
    this.y=y;
    this.vx=vx;
    this.vy=vy;
    this.g=9.81;
    this.timeIncrement=1/20;
    this.radius=radius;
    this.color=color;
    this.friction=1;
   
    this.get_y_displacement=()=>{
        g=this.g;

        t=this.timeIncrement;
        var prev_vy=this.vy;
        this.vy=Math.min(900,this.vy + (g*t)); //terminal velocity
        
        s=0.5 * (prev_vy+this.vy)*t;
        return s;
    }

    this.get_x_displacement=()=>{
        t=this.timeIncrement;
        sx=(this.vx*t) ;
        return sx;
    }

    this.ballCollision=()=>{
        balls.forEach(ball=>{
            if (  Math.abs(ball.x-this.x)<(ball.radius+this.radius)
            && 
            Math.abs(ball.y-this.y)<(ball.radius+this.radius)
            ){
                ball.vx*=-1;
                ball.vy*=-1;
                this.vx*=-1;
                this.vy*=-1;

            }
        })


    }
    this.wallCollision=()=>{
        if (this.y+this.radius>=canvas.height || this.y-this.radius<=0 )
        {
            this.y=Math.min(canvas.height-this.radius,this.y);

            if(this.y<=this.radius){this.y=this.radius;}
            this.vy=-this.vy;
        }
        if ( this.x+this.radius>=canvas.width || this.x<=this.radius)
        {
                    
            this.x=Math.min(canvas.width-this.radius,this.x);
     
            this.vx=-this.vx*this.friction;
        }

    }
    this.checkCollision=()=>{
        this.ballCollision();
        this.wallCollision();

    }
    this.update=() =>{
        this.checkCollision();
        this.y+=this.get_y_displacement();
        this.x+=this.get_x_displacement();
    }
    this.draw=()=>{
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,0,Math.PI*2);
        ctx.fill();
        ctx.fillStyle=this.color;
        ctx.closePath();
        ctx.save();

    }
}

function init(n){
    for (let i=0;i<n;i++){
        
        let vx=randomRange(-60,60);
        let vy=randomRange(-70,70);
        let r=randomRange(1,45);
        let x=randomRange(r,canvas.width-r);
        let y=randomRange(r,canvas.height-r);

        let color='#'+Math.floor(Math.random()*16777215).toString(16);
        a=new Ball(x,y,r,
                    '#'+Math.floor(Math.random()*16777215).toString(16),
                    vx,
                    vy);
        balls.push(a);
      
        
    }
    
}

function randomRange(min, max) { // min and max included 
    return Math.floor(Math.random() * (max - min + 1) + min)
  }

function pauseAnimation(){
    isPaused= !isPaused;
}
function animate(){
    
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,canvas.width,canvas.height);
    balls.forEach(ball=>{
    if(!isPaused){
       ball.update(); 
       ball.draw();
    }
    ball.draw();
    })

    

}
init(10);
animate();
window.addEventListener("click",pauseAnimation);

I expected the balls to interact realistically, bouncing off each other upon collision, and bouncing off the canvas boundaries smoothly. However, the code currently exhibits issues where some balls clip through each other, and others stick together upon collision. I’ve tried to review the collision logic, but I can’t identify the source of the problem.

How to submit a form with autosuggest with Javascript and Python flask

I use Python Flask and Javascript (jQuery) to create a simple web form with autosuggest (from external API). My code works partially, but I am struggling with the routing/functions in Flask and autosuggest in Javascript. The current code below shows the items from the autosuggest. I can select an item, as well as filling the other fields in the webform, but when submitting the form, it returns JSON file. I don’t know how to pass the result of one function to the other function. I expect to be able to do the following in the same HTML page (single page application):

  1. Display items from autosuggest, when typing in a field in the webform
  2. Select an item from autosuggest and show the item in the field filled
  3. Fill other fields (without autosuggest)
  4. Hit submit button
  5. See the query results page (detail not described in this question)

Can somebody help me? Minimal change is preferred, but, if it is better to refactor the code structure, that is also fine. Many thanks!

layout.html

        <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
        <!-- <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script> -->
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
        <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" crossorigin="anonymous"></script>
        <script>
            $( function() {    
                $( "#project" ).autocomplete({
                    source : function(request, response) {
                        console.log(request.term);
                        $.ajax({
                            type: "POST",
                            url : "http://127.0.0.1:5000/database",
                            dataType : "json",
                            cache: false,
                            data : {
                                entity_type : request.term
                            },
                            success : function(data) {
                                console.log(data);
                                response(data);
                            },
                            error: function(jqXHR, textStatus, errorThrown) {
                                console.log(textStatus + " " + errorThrown);
                            }
                        });                        
                    },
                    minLength : 2,
                    focus: function( event, ui ) {
                        $( "#project" ).val( ui.item.name );
                        return false;
                    },
                    select: function( event, ui ) {
                        $( "#project" ).val( ui.item.label );
                        $(event.target).val(ui.item.id); // Set the input value to the selected item's name
                        return false;
                    }
                })
                .autocomplete( "instance" )._renderItem = function( ul, item ) {
                return $( "<li>" )
                    .append( "<div><b>" + item.id + ":" + item.name + "</b>" + " " + item.description + "</div>" )
                    .appendTo( ul );
                };
            } );

database.html

<form method="post" id="search-form">
    <label for="entity_type">Please specify an entity type </label>
    <input type="text" 
            name="entity_type"
            id="project"
            size="150"
            placeholder="Specify entity type here (e.g. Q5)"
            value="{{ request.form['entity_type'] }}"></input>
    <label for="country">Please specify a country</label>
    <input type="text" 
            name="country"
            size="50"
            placeholder="Specify a country (e.g. Netherlands)"
            value="{{ request.form['country'] }}"></input>
    <button type="submit">Search</button>
</form>

database/views.py

@database.route('/database/')
def upload_form():
    return render_template('database.html')

@database.route('/database/', methods=('GET', 'POST'))
# This is the autosuggest function
def autosuggest():
    term = request.form['entity_type']
    print ('term: ', term)
    json_url = f'https://wikidata.reconci.link/en/suggest/entity?prefix={term}'
    headers = ''
    r = requests.get(json_url, headers=headers, timeout=3)
    json_data = r.json()
    json_data = json_data['result']
    resp = jsonify(json_data)
    resp.status_code = 200
    return resp

# This is the main function of the webform which tries to use the selected item from the autosuggest function. The webform also contains input fields without autosuggest.
@database.route('/database/', methods=('GET', 'POST'))
def database():
    if request.method == 'POST':        
        # I don't know how to pass the selected item from autosuggest function in here. 1st variable is for autosuggest, the 2nd one is without it
        entity_type = autosuggest()
        country = request.form['country']
        # More code here #
        return render_template('database.html', total_results=total_results, messages2=messages2, messages3=messages3, input=input)
    else:
        render_template('database.html')
    return render_template('database.html')

Bokeh: major_label_overrides doesn’t get updated after CustomJS callback

I have written the code below to make a plot which can be updated when users apply some filters to the data. After selecting a value from the dropdown, the callback updates everything as expected, except for the yaxis.major_label_overrides (which writes the name (string) on top of the y-axis ticker (integer).

When I investigated the console, I have noticed the following exception in y_axis.major_label_overrides:
Exception in browser console
Here is the full exception: Exception: TypeError: ‘caller’, ‘callee’, and ‘arguments’ properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.invokeGetter (< anonymous > :3:28).

After some researches, I’m not sure how to solve this exception in this specific situation (and whether or not it is the cause of the problem).

What it looks like before filter is applied:
Plot before filter is applied

What it looks like after filter is applied:
Plot after filter is applied

It doesn’t through any error in the console, but the expected output after the filter is applied is a y-axis as below:

  • “Joe_updated” instead of “Bob”,
  • “Guy_updated” instead of “Joe”.

I’m using Google Chrome to open the output file. Bokeh version is 3.2.2 and Python is 3.11.4.

Below is my code:

### Packages ###
from math import pi
import bokeh.events as bev
import bokeh.layouts as bla
import bokeh.models as bmo
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
from bokeh.transform import factor_cmap


### Data ###
data = [
    ['medium', 'F', 'F', 108, 'Bob', 767.02, 'medium'],
    ['bad_medium_bad', 'F', 'DB_D_F', 202, 'Joe', 542.9, 'bad'],
    ['bad_medium_bad', 'DB', 'DB_D_F', 202, 'Joe', 5.8, 'bad'],
    ['bad_medium_bad', 'D', 'DB_D_F', 202, 'Joey', 0.0, 'medium'],
    ['medium', 'F', 'F', 810, 'Francis', 679.7, 'medium'],
    ['medium', 'F', 'F', 355, 'James', 354.6, 'medium'],
    ['medium', 'F', 'F', 288, 'Suze', 23.1, 'medium'],
    ['medium', 'F', 'F', 281, 'Anna', 36.5, 'medium'],
    ['medium_medium_medium', 'F', 'DB_D_F', 249, 'Guy', 673.1, 'medium'],
    ['medium_medium_medium', 'DB', 'DB_D_F', 249, 'Guy', 13.2, 'medium'],
    ['medium_medium_medium', 'D', 'DB_D_F', 249, 'Guy B', 99.1, 'medium']
]

data = pd.DataFrame(data, columns=['overall_status', 'group', 'overall_group', 'id', 'name', 'amount', 'status'])

data.insert(loc=0, column="y_ticker", value=0, allow_duplicates=True)

# replace id by a shorter number that can be used to place data on y_axis in a neat way.
for i in list(data.index.values):
    if i == 0:
        data.loc[i, "y_ticker"] = 0
    else:
        if data.loc[i-1, "id"] == data.loc[i, "id"]:
            data.loc[i, "y_ticker"] = data.loc[i-1, "y_ticker"]
        else: 
            data.loc[i, "y_ticker"] = data.loc[i-1, "y_ticker"] + 1


### Setup ###
output_file('test_dashboard.html')

source = bmo.ColumnDataSource(data.to_dict(orient='list'))

filtered_data = bmo.ColumnDataSource(data.to_dict(orient='list'))


### Plot ###
cmap = {
    'good': '#006B3D',
    'medium': '#FF980E',
    'bad': '#D3212C',
}

TOOLS = "hover,save,ypan,reset,wheel_zoom"

p = figure(title='Dashboard for testing',
           x_range=bmo.FactorRange(), x_axis_label = "Group",
           y_range=bmo.Range1d(), y_axis_label = "Name",
           x_axis_location="above", width=600, height=500,
           tools=TOOLS, toolbar_location='below',
           tooltips=[('Name', '@name'), ('Amount', '@amount')]
           )


# create rectangles
p.rect(x="group", y="y_ticker", width=1, height=1, source=filtered_data, legend_field='status',
           color=factor_cmap("status", palette=list(cmap.values()), factors=list(cmap.keys())),
           line_color=None)


# create initial label_overrides
p.yaxis.major_label_overrides = dict(zip(filtered_data.data['y_ticker'], filtered_data.data['name']))
p.yaxis.ticker = list(range(0, len(p.yaxis.major_label_overrides)))


# create inital ranges
p.x_range.factors = list(np.unique(filtered_data.data['group']))
p.y_range.start = 0

# adapt y_range.end to the length of p.yaxis.major_label_overrides
# (I have thousands of rows in the real dataset)
max_y_range = 20

if(len(p.yaxis.major_label_overrides) < 20):
    max_y_range = len(p.yaxis.major_label_overrides)

p.y_range.end = max_y_range

p.xgrid.grid_line_color = '#FFFFFF'
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "15px"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = pi / 3
p.x_range.range_padding = 1


### Define dropdown options ###
dropdown_group_options = [
                       'All'
                   ] + [
                       cat for i, cat in enumerate(sorted(data['group'].unique()), 2) # à quoi sert le 2 ici ?
                   ]


### Generate dropdown widget ###
dropdown_group = bmo.Select(title='group', value=dropdown_group_options[0], options=dropdown_group_options)


### Callback ###
callback = bmo.CustomJS(
    args=dict(unfiltered_data=source, 
              filtered_data=filtered_data, 
              p=p,
              y_axis=p.yaxis[0],
              dropdown_group=dropdown_group),
    code="""

// utils

function getKeyByValue(object, value) {
    return Object.keys(object).find(key => object[key] === value);
}



var source = unfiltered_data.data;

// create a variable for each column of the unfiltered_data

var group_or = source['group'] ;
var overall_group_or = source['overall_group'] ;
var id_or = source['id'] ;
var name_or = source['name'] ;
var amount_or = source['amount'] ;
var status_or = source['status'] ;
var overall_status_or = source['overall_status'] ;
var y_ticker_or = source['y_ticker'] ;
 

// init filtered_data  

filtered_data.data['group'] = [] ;
filtered_data.data['overall_group'] = [] ;
filtered_data.data['id'] = [] ;
filtered_data.data['name'] = [] ;
filtered_data.data['amount'] = [] ;
filtered_data.data['overall_status'] = [] ;
filtered_data.data['status'] = [] ;
filtered_data.data['y_ticker'] = [] ;


// get value from dropdown

var f_sec = dropdown_group.value;


// push matching rows in filtered_data

var match = 0

for(var i=0; i < overall_status_or.length; i++){
    if((overall_group_or[i].search(f_sec) != -1 || f_sec == 'All')){
        
        filtered_data.data['group'].push(group_or[i]) ;
        filtered_data.data['overall_group'].push(overall_group_or[i]) ;
        filtered_data.data['id'].push(id_or[i]) ;
        filtered_data.data['name'].push(name_or[i]) ;
        filtered_data.data['amount'].push(amount_or[i]) ;
        filtered_data.data['overall_status'].push(overall_status_or[i]) ;
        filtered_data.data['status'].push(status_or[i]) ;

        // I use the below if statement to 'reset' y_tickers value (start=0, by=1)
        // it allows me to keep equally spread values on the y_axis
        if(match == 0){
            filtered_data.data['y_ticker'].push(match);
        } else if(id_or[i] == id_or[i-1]){
            filtered_data.data['y_ticker'].push(filtered_data.data['y_ticker'].at(-1));
        } else{
            var new_y_ticker = filtered_data.data['y_ticker'].at(-1) +1
            filtered_data.data['y_ticker'].push(new_y_ticker)
        }
        ++match
    }
}

console.log(filtered_data.data)


// delete the initial mapping
y_axis.major_label_overrides.clear() ;


// create new y_tickers

const y_tickers = [...new Set(filtered_data.data['y_ticker'])]
console.log(y_tickers)

y_axis.ticker.ticks.length = y_tickers.length ; 
y_axis.ticker.ticks = y_tickers ;


// update mapping in major_label_overrides
for(const element of y_tickers){

    var key_name = getKeyByValue(filtered_data.data['y_ticker'], element) ;

    y_axis.major_label_overrides.set(element, filtered_data.data['name'][key_name] + '_updated') ;

}


// get new x_range
var new_x_range = [...new Set(filtered_data.data['group'])];

// update existing x_range with new factors
p.x_range.factors.length = new_x_range.length

for(var i=0; i < new_x_range.length; i++){
    p.x_range.factors[i] = new_x_range[i];
}


// adapt y_range to y_tickers length

var max_y_range = 20

if(y_tickers.length < 20){
    max_y_range = y_tickers.length
}

p.y_range._reset_start = 0 ;
p.y_range._reset_end = max_y_range ;


console.log(y_axis.major_label_overrides)


// update everything                     
filtered_data.change.emit();
p.reset.emit();
p.change.emit();
y_axis.change.emit();

"""
)

### Link actions ###
dropdown_group.js_on_change('value', callback)


show(bla.column(dropdown_group, p))

Thank you in advance for the time you might spend on this question 🙂

Leaflet : how to duplicate a map and display it in another div?

I am creating a Leaflet map, then doing a lot of stuff (750 lines of code, mostly adding layers and SVG elements with d3.js). So far I am doing everything using a map1 div and variable :

const map1 = L.map('map1')
...

But I would like to be able to duplicate this map in another div (map2), without having to rewrite everything for the 2nd map.

<div id='map1'></div>
<div id='map2'></div>

Is it even possible to do this ? The final goal would be to have an fixed map (disabling zoom and drag & drop), and an interactive one next to it.

How to get value from sub array in React

I would like to get the current value from the sub array list.

Here is my function.

  const getCurrentValues = (index: any) => {
    console.log(index);
    console.log(fields);

    console.log(fields[index]);
  };

codesandbox

After click the “Get value” button, it can get the current array list.

For example,
Input “1” in Sub List #0, then the console.log will show “1”
Input “test” in Sub List #1, then the console.log will show “test”

Now, my code seem can not get correct output after click “append” button. what am I doing wrong here?

Javascript expressions in SQL query

I’m trying to build a low-code platform involving sql query submissions through the browser app. This is something similar to what most of the low-code platform support out-of-the-box.

Refer the below query submission.

SELECT * 
FROM orders o 
where o.customer_id = {{selectComponent.value}};

The above query has a predicate involving a javascript expression, which is a value the user selects from a dropdown. The expressions could be more complex in nature depending on the complexity of the module and query.

I have the following queries.

  1. The sql query needs to be execute the server side but the predicate has to be evaluated at the client side. How to connect them?

  2. If the query is brought to the client side for predicate evaluation, it brings the risk of sql injections. How to handle it?

I’m still building the conceptual model to solve this problem. I’m quite aware of the server-side prepared statements with named and positional parameters. But not able to think around connecting both the ends in an efficient and secured manner.

Validating Javascript Console Errors and Warnings with Java, Selenium, and Cucumber

I am working on automating some tests using Cucumber with Java and Selenium WebDriver. I have a step defined to check the browser console for any errors or warnings after the application loads. The step is defined as follows:

@Then("he checks if there are no console errors or warnings")
public void checkConsoleForErrorsAndWarnings() {
    LogEntries logEntries = SelectorHelper.getDriver().manage().logs().get(LogType.BROWSER);
    for (LogEntry entry : logEntries) {
        String message = entry.getMessage();
        assertFalse(message.contains("ERROR"), () -> "Console error found: " + message);
        assertFalse(message.contains("WARN"), () -> "Console warning found: " + message);
    }
}

The problem I am facing is that even if there are warnings in the console, this step passes without any assertion failure. I suspect that the message.contains(“WARN”) condition is not working as expected, or perhaps the log entries are not being captured correctly.

I am looking for alternative approaches to solve this issue. Does anyone have suggestions on how to modify this step or a different method to accurately capture and assert any console errors or warnings? Any help or suggestions would be greatly appreciated.