Issue with Replacing Path Variables in URL Dynamically in Apache Camel During Unit Test (Port Defaults to 80)

I’m working on a project that uses Apache Camel, and I’m trying to dynamically replace a path variable in a service URL using a header. The URL is of the form:

/abc/v1/{clientId}/lookup

In my route, I’m replacing {clientId} with the actual value from the message header using the following code:

.setHeader(Exchange.HTTP_URI, builder.simple(serviceUrl.replace("{clientId}", "${header.clientId}")))

This works perfectly when running the application normally, and the value of clientId is replaced dynamically at runtime. However, when running my Junit tests, I encounter an issue where the port of the URL is automatically changed to port 80, no matter what port I specify in my mock service configuration.

For example, if I configure a mock service URL like http://localhost:8080, it gets replaced with http://localhost:80 during the test run, leading to connection failures due to the incorrect port.

Can someone please help me? When I remove this line:
.setHeader(Exchange.HTTP_URI, builder.simple(serviceUrl.replace("{clientId}", "${header.clientId}")))
then my unit test code works fine.

Failed to execute ‘setRemoteDescription’ on ‘RTCPeerConnection’ on webrtc

So I am following the tutorial by TauhidCodes on youtube here: https://www.youtube.com/watch?v=MBOlZMLaQ8g

It is a little different because I am using reverse urls for the different room names.

I am implementing a video call system that allows more than 3 users and above to join by entering the appropriate url like https://127.0.0.1:8000/video/test/. I open 2 tabs in the same window and press start call for both of them and they both say the error.

Error

test/:1 Uncaught (in promise) InvalidStateError: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote answer sdp: Called in wrong state: stable
<!DOCTYPE html>
<html>

<head>
  <style>
    button {
      border: 0;
      background-color: orange;
      padding: 10px;
      color: white;
      border-radius: 7px;
    }

    video {
      border-radius: 15px;
    }

    .videoContainer {
      display: flex;
      margin: 20px;
      width: 640px;
    }

    .videoContainer h2 {
      color: white;
      position: relative;
      bottom: -380px;
      left: -350px;
      width: max-content;
    }

    #meet {
      display: flex;
    }

    #recordButton.recording {
      background-color: red;
    }

    #downloadButton {
      background-color: #4caf50;
    }

    button:disabled {
      background-color: #cccccc;
      cursor: not-allowed;
    }
  </style>
  <title>A Free Bird Video Call</title>
  <script src="https://meet.jit.si/external_api.js"></script>
</head>
{% load static %}
<body>
  <div id="meet">
    <button id="videoOff" onclick="toggleVideoOff()" disabled>Video Off</button>
    <button id="audioMute" onclick="toggleAudioMute()" disabled>Mute Audio</button>
    <div id="remote-videos">
      <div id="videoContainer">
        <video id="localVideo" autoplay playsinline></video>
        <h2>{{ request.user.full_name }}</h2>
      </div>
    </div>
    <!-- <div class="videoContainer">
      <video id="remoteVideo" autoplay playsinline></video>
      <h2></h2>
    </div> -->
  </div>

  <div>
    <button onclick="startCall()">Start Call</button>
    <button id="recordButton" onclick="toggleRecording()" disabled>
      Start Recording
    </button>
    <button id="downloadButton" onclick="downloadRecording()" disabled>
      Download Recording
    </button>
    <button id="shareScreenButton" onclick="shareScreen()">Share Screen</button>
  </div>
  <div id="chat">
    <h3>Chat</h3>
    <div id="messages">
      <ul id="messageList"></ul>
      <input type="text" id="messageInput" placeholder="Type your message here...">
      <button id="sendMessageButton">Send</button>
    </div>
  </div>
  <input type="hidden" id="user_id" value="{{ request.user.id }}">
<script src="{% static 'js/video_call.js' %}" type="text/javascript" data-room-name="{{ room_name }}"></script>
</body>

</html>

var mapPeers = {}

var userId = document.getElementById('user_id').value;
console.log('User ID:', userId);
var ws;
function webSocketOnMessage(e) {
    var parsedData = JSON.parse(e.data);

    var peerUsername = parsedData['peer'];
    var action = parsedData['action'];
    

    
    var receiver_channel_name = parsedData['message']['receiver_channel_name'];

    if (action == 'new-peer') {
        createOfferer(peerUsername, receiver_channel_name);

        return;
    }

    if (action == 'new-offer') {
        var offer = parsedData['message']['sdp'];
        createAnswerer(offer, peerUsername, receiver_channel_name);
        return;
    }

    if (action == 'new-answer') {
        var answer = parsedData['message']['sdp'];
        
        var peer = mapPeers[peerUsername][0];

        peer.setRemoteDescription(answer);

        return;
    }
}

function startCall() {
    
    
    var loc = window.location;
    var wsStart = 'ws://';
    if (loc.protocol === 'https:') {
        wsStart = 'wss://';
    }
    var roomName = document.querySelector('script[src*="video_call.js"]').dataset.roomName;
    var endpoint = wsStart + loc.host + '/ws/webrtc/' + roomName + '/';
    ws = new WebSocket(endpoint);

    ws.addEventListener('open', (e) => {
        console.log('Connected to WebSocket server.');

        sendSignal('new-peer', {});
    });
    ws.addEventListener('message', webSocketOnMessage);

    ws.addEventListener('error', (e) => {
        console.log('WebSocket error:', e);
    });

    ws.addEventListener('close', (e) => {
        console.log('WebSocket connection closed:', e);
    });
}

var localStream = new MediaStream();

const constraints = {
    'video': true,
    'audio': true
}

const localVideo = document.getElementById('localVideo');

var videoOffButton = document.getElementById('videoOff');
var audioMuteButton = document.getElementById('audioMute');

var userMedia = navigator.mediaDevices.getUserMedia(constraints)
    .then((mediaStream) => {
        localStream = mediaStream;
        localVideo.srcObject = localStream;
        localVideo.muted = true;

        var audioTracks = localStream.getAudioTracks();
        var videoTracks = localStream.getVideoTracks();

        audioTracks[0].enabled = true;  
        videoTracks[0].enabled = true;

        videoOffButton.addEventListener('click', () => {
            videoTracks[0].enabled = !videoTracks[0].enabled;

            if (videoTracks[0].enabled) {
                videoOffButton.textContent = 'Video Off';
                return;
            } 

            videoOffButton.textContent = 'Video On';
        });

        audioMuteButton.addEventListener('click', () => {
            audioTracks[0].enabled = !audioTracks[0].enabled;

            if (audioTracks[0].enabled) {
                audioMuteButton.textContent = 'Mute Audio';
                return;
            } 

            audioMuteButton.textContent = 'Unmute Audio';
        });
    })
    .catch((err) => {
        console.error("Error accessing media devices:", err);
    });



function sendSignal(action, message) {
    var jsonStr = JSON.stringify({
    'peer': userId,
    'action': action,
    'message': message,
    })

    ws.send(jsonStr);

}

function createOfferer(peerUsername, receiver_channel_name) {
    var peer = new RTCPeerConnection(null);

    addLocalTracks(peer);

    var dc = peer.createDataChannel('channel');
    dc.addEventListener('open', () => {
        console.log('Data channel is open');
    });
    dc.addEventListener('message', dcOnMessage);

    var remoteVideo = createVideo(peerUsername);
    setOnTrack(peer, remoteVideo);

    mapPeers[peerUsername] = [peer, dc];

    peer.addEventListener('iceconnectionstatechange', () => {
        var iceConnectionState = peer.iceConnectionState;

        if (iceConnectionState === 'disconnected' || iceConnectionState === 'failed' || iceConnectionState === 'closed') {
            delete mapPeers[peerUsername];

            if (iceConnectionState != 'closed') {   
                peer.close();
            }

            removeVideo(remoteVideo);
        }
    });

    peer.addEventListener('icecandidate', (event) => {
        if (event.candidate) {
            console.log("Sending ICE candidate", JSON.stringify(peer.localDescription));
            return;
        }

        sendSignal('new-offer', {
            'sdp': peer.localDescription,
            'receiver_channel_name': receiver_channel_name,
        });
        
    });

    peer.createOffer()
    .then((offer) => {
        peer.setLocalDescription(offer);
    })
    .then(() => {
        console.log('local description set successfully');
    });
}

function createAnswerer(offer, peerUsername, receiver_channel_name) {
    var peer = new RTCPeerConnection({
        'iceServers': [
            {'urls': 'stun:stun.l.google.com:19302'},
            {'urls': 'stun:stun1.l.google.com:19302'},
            {'urls': 'turn:turn.brii.me:5349?transport=udp', 'credential': 'brii', 'username': 'brii'},
            {'urls': 'turn:turn.anyfirewall.com:443?transport=tcp', 'credential': 'webrtc', 'username': 'webrtc'},
        ]
    });

    addLocalTracks(peer);

    var remoteVideo = createVideo(peerUsername);
    setOnTrack(peer, remoteVideo);

    peer.addEventListener('datachannel', (event) => {
        peer.dc = event.channel;
        peer.dc.addEventListener('open', () => {
            console.log('Data channel is open');
        });
        peer.dc.addEventListener('message', dcOnMessage);

        mapPeers[peerUsername] = [peer, peer.dc];
    });

    

    peer.addEventListener('iceconnectionstatechange', () => {
        var iceConnectionState = peer.iceConnectionState;

        if (iceConnectionState === 'disconnected' || iceConnectionState === 'failed' || iceConnectionState === 'closed') {
            delete mapPeers[peerUsername];

            if (iceConnectionState != 'closed') {   
                peer.close();
            }

            removeVideo(remoteVideo);
        }
    });

    peer.addEventListener('icecandidate', (event) => {
        if (event.candidate) {
            console.log("Sending ICE candidate", JSON.stringify(peer.localDescription));
            return;
        }

        sendSignal('new-answer', {
            'sdp': peer.localDescription,
            'receiver_channel_name': receiver_channel_name,
        });
        
    });

    peer.setRemoteDescription(offer)
    .then(() => {
        console.log('remote description set successfully for %s', peerUsername);

        return peer.createAnswer();
    })
    .then(a => {
        console.log('Answer created');

        peer.setLocalDescription(a);
    })
}
function addLocalTracks(peer) {
    localStream.getTracks().forEach((track) => {
        peer.addTrack(track, localStream);
    });

    return;
}

var messageList = document.querySelector('#messageList');
function dcOnMessage(e) {
    var message = e.data;

    var li = document.createElement('li');
    li.appendChild(document.createTextNode(message));
    messageList.appendChild(li);
}

function createVideo(peerUsername) {
    var videoContainer = document.querySelector('#remote-videos');

    var remoteVideo = document.createElement('video');

    remoteVideo.id = `remote-video-${peerUsername}`;
    remoteVideo.autoplay = true;
    remoteVideo.playsinline = true;

    var videoWrapper = document.createElement('div');
    videoContainer.appendChild(videoWrapper);
    videoWrapper.appendChild(remoteVideo);
    return remoteVideo;
}

function setOnTrack(peer, remoteVideo) {
    var remoteStream = new MediaStream();

    remoteVideo.srcObject = remoteStream;

    peer.addEventListener('track', async (event) => {
        remoteStream.addTrack(event.track, remoteStream);
    });
}

function removeVideo(video) {
    var videoWrapper = video.parentNode;

    videoWrapper.parentNode.removeChild(videoWrapper);
}

I tried to look at the code but there wasn’t much different. I don’t think it has any mistakes… I am expecting it to show two video streams, one local and one remote using two tabs with the video call room open. Before, it showed that there were 3 video streams when I pressed start call but only on one tab. The other tab had the same error I mentioned. I am trying to make this work because they are a non profit and don’t want to spend unneccessary money.

How to point to an object inside an object and display it without knowing the name

How to point to an object inside an object and display it without knowing the name.

I just want to display the values ​​of the objects inside person.
using the if I only want to display the values ​​of the object.
But how should I reference it to display it?

const person = { name:"Jack", family:"Miller", age: 27, cars:{car1:"Bens", car2:"Lexus"}}


   for (let x in person){
  if(typeof person[x] === "object"){
    
    // for (let x in ??){document.write(?? + ", ")}

    }else{
        document.write("_" + "<br>")
  }
}

Expected output:

_

_

_

Bens, Lexus

Monaco JavaScript editor autocomplete menu clipped

Running a Monaco editor (version 0.50.0) in a complex web-based app. I recently discovered when the editor is being used in a modal dialog of fixed size, the autocomplete menu can be displayed such that its contents are clipped. Here’s an example, where the gray line at the bottom is a border in the editor’s enclosing div:

enter image description here

If the editor is scrolled up a bit, the menu is displayed as expected:
enter image description here

In either case, the menu does work (arrow keys and selection behave as expected). I would have expected in the clipped case that the editor should have realized the space limitation and displayed the menu above the edited line.

The problem occurs no matter the browser on MacOS (Firefox, Chrome, Safari). I have no easy way to test it on any other OS.

This seems like a Monaco bug but I wonder if anyone recognizes this problem and has a solution.

How to implement Select All functionality to checkBoxGroupInput in R shiny app?

I am trying to add Select All option to my checkbox inputs so that if I check ‘Select All’ all other option are selected. If I unselect the ‘Select All’ all other option get unselected. And if I individually select other options then the ‘Select All’ checkbox need to automatically unselect and only the items individually selected are checked. I am using JScript but it does not work. Here is a simplified example code that is not working.

library(shiny)

ui <- fluidPage(
  titlePanel("Checkbox Group with Select All"),
  
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("filter_grp", "Select Options:", 
                         choices = c("Select All" = "all", 
                                     "Option 1" = "opt1", 
                                     "Option 2" = "opt2", 
                                     "Option 3" = "opt3"), 
                         selected = c("all", "opt1", "opt2", "opt3"))  # All options including "Select All" selected by default
    ),
    
    mainPanel(
      textOutput("selected_options")
    )
  ),
  
  tags$script(HTML("
    $(document).on('shiny:inputchanged', function(event) {
      if (event.name === 'filter_grp') {
        var selected = event.value || [];
        if (selected.includes('all')) {
          if (selected.length === 1) {
            // If 'Select All' is the only selected option, select all others
            $('#filter_grp input').prop('checked', true);
            Shiny.setInputValue('filter_grp', ['all', 'opt1', 'opt2', 'opt3'], {priority: 'event'});
          } else {
            // If 'Select All' is deselected, clear all selections
            $('#filter_grp input').prop('checked', false);
            Shiny.setInputValue('filter_grp', [], {priority: 'event'});
          }
        } else {
          // If any other option is selected, remove 'Select All' from selection
          if (selected.length === 3) {
            $('#filter_grp input[value="all"]').prop('checked', false);
            Shiny.setInputValue('filter_grp', selected.filter(function(item) { return item !== 'all'; }), {priority: 'event'});
          }
        }
      }
    });
  "))
)

server <- function(input, output, session) {
  output$selected_options <- renderText({
    paste("Selected options:", paste(input$filter_grp, collapse = ", "))
  })
}

shinyApp(ui, server)

Is it possible to mock a Date in Javascript?

Is it possible to mock the Date returned from this service so that it can reflect different timezones in a Jasmine/Karma context? I’m not looking to simplify modify the hours/minutes to reflect UTC, the offset will be modified too. The mock object will behave as if new Date() was created from a browser in that timezone.

export class TimeService {
  static getCurrentDate(): Date {
    return new Date();
  }
}

How do I interpret this JOI validation code (version 17.8.3)?

I’ve got the follow JOI code for validating data:

const abcSchema = Joi.object().keys({
  value: Joi.when('...objectType', {
    is: Joi.string().valid('Unknown').insensitive(),
    then: Joi.optional().allow(null),
    otherwise: Joi.number().positive().required(),
  });

export const schema = Joi.object().keys({ abc: abcSchema });

Please let me know if I’m interpreting this correctly: it’s saying that on an object where the objectType field has a value of ‘Unknown’ (case insensitive), the abc field is optional and can be null. Otherwise (if it’s a different value than null or the objectType field is not ‘Unknown’), then the abc field is required and must be a positive number.

Is this correct?

What if I’m trying to validate an object that looks like this:

{
    ...
    "objectType": {
        "type": "UNKNOWN",
        ...
    }
    ...
    "abc": {
        "value": null,
        ...
    }
    ...
}

…and it gives back this validation message: “abc : value” must be a number”

So abc.value is null, and objectType.type is ‘UNKNOWN’ yet it seems to be falling back on the otherwise validation rule. Why is that?

I’m using Joi 17.8.3.

Why does input type=”date” not reflect the user’s local timezone and sometimes display a day earlier or later?

I’m making a task app that takes a form to create a task. To set the due date for the task I created a html input using the date type. It works and looks great, but I noticed that the date can vary a day before or after if I set a date and the local time is 23 hs.

I seached for this problem and it seems that the date type is set by default to UTC time. Great! But how can I fix it so it accepts just the date as it is instead of taking account timezones? It seems silly, if I’m choosing a date from a calendar why take timezones into consideration.

I’m making the form implementation with DOM functions in JS. The input is set this way if it helps:

    const dateInput = document.createElement("input");
    dateInput.type = "date";
    dateInput.name = "due-date";

How can I set the date input so it just outputs the day chosen in the calendar without any timezones?

Conflicts with RxJS switchMap and Appcues Script in a Module Federation Microfrontend Architecture

I’m encountering a persistent issue when integrating the Appcues script into our Angular application, which utilizes Module Federation for implementing microfrontends. The problem arises specifically when the Appcues script is loaded, affecting the behavior of RxJS switchMap operators used throughout our application.
Appcues is a third party system to track user loggins and to display banners in the web where it is integrated.

Problem Description:

In our setup, we dynamically inject the Appcues script into one of our microfrontends. The script is added to the DOM using the following JavaScript code:

const script = document.createElement('script');
script.async = true;
script.id = 'appcues';
script.src = 'https://fast.appcues.com/Id_Value.js'; // Example src
document.body.appendChild(script);

This microfrontend architecture is managed with Module Federation, allowing us to operate multiple independent builds as part of a cohesive platform.

Issue Observed:

The issue does not occur immediately after loading the script. Instead, it appears after navigating away from the initial page (where the script is loaded) and then interacting with components that rely on RxJS’s switchMap. The error thrown is:

TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

This error suggests a collision or interference in the handling of observables, possibly caused by how Appcues manipulates the global environment or interacts with the JavaScript event loop, impacting RxJS operations.

Steps to Reproduce:

Load the Appcues script in one of the microfrontends.
Perform operations that trigger RxJS switchMap within this or other microfrontends.
Navigate to another part of the application and return to the previous microfrontend.
The error begins to appear intermittently, often requiring a page refresh to resolve temporarily.

What I’ve Tried:

Ensuring that the script is loaded asynchronously and checked for errors.
Delaying the loading of the Appcues script to allow other initializations to complete.
Using Angular’s NgZone to isolate the script loading from Angular’s change detection mechanisms.
Suspicions:

It seems like the Appcues script might be altering some global variables or aspects of the JavaScript runtime that RxJS depends on, particularly around how asynchronous operations are handled.

Questions:

Has anyone experienced similar issues with Appcues or other third-party scripts interfering with RxJS?
Are there known compatibility issues with Appcues and RxJS when used in a microfrontend architecture managed by Module Federation?
What strategies might be effective in isolating the third-party script’s effects from the rest of the application?
Any insights or suggestions on how to address these issues without removing Appcues would be greatly appreciated. Thank you!

Execute code at parent window by child iframe when the child iframe is destroyed

In javascript, can the function in the setTimeout be executed after the parent kills the child iframe?

The following code illustrated that the function

alert("123") 

cannot be executed if the child iframe is killed, even it is defined in the iframe’s parent.

In test1.html:

<!DOCTYPE html>
<html>
<body>
    <button onclick="kill()">Click to kill</button>
    <iframe src="./test2.html"></iframe>
    <script>
    function kill(){  // kill all iframes
        var iframes = document.querySelectorAll('iframe'); 
        for (var i = 0; i < iframes.length; i++) {
            iframes[i].parentNode.removeChild(iframes[i]);
        }
    }
     </script>
</body>
</html>

In test2.html (placed on same folder and run in same origin as test1.html:

<!DOCTYPE html>
<html>
<body>
    <script>window.parent.setTimeout( ()=> window.parent.alert("123"), 5000)</script>
</body>
</html>

The above codes were tested in Chrome version 133.0.6943.127 in Windows 11.

So my questions are

  1. Why the code cannot be executed when the child iframe is killed even if it is defined in the scope of the parent window? Is it related to the garbage collection mechanism and handling of execution context of the javascript engine?
  2. Is there any way to allow code to be run after the child iframe is destroyed, without modifying the parent window’s code (i.e. test1.html)?

How to target all options button to be disabled

I have created a quiz element, with four options in it.how should I make disabled all option buttons, when any one of them is clicked.

const obj = {
    id:1,
    correctAns : "Three",
    opt:["One","Two","Three","Four"],
    question:"There are how many sides in a triangle?"
}
let quesElement = document.getElementById('ques');
let optionsElement = document.getElementById('options');
let scoreElement = document.getElementById('score');
let heading = document.createElement('h2');
heading.textContent=`${obj.question}`;
quesElement.appendChild(heading);
let ans;
let score = 0;
obj.opt.forEach((x)=>{
    let button_div = document.createElement('div');
    let option = document.createElement('button');
    option.classList.add('opt-btn');
    option.textContent = `${x}`;
    button_div.appendChild(option);
    options.appendChild(button_div);
    option.addEventListener('click',()=>{
        if(x==obj.correctAns){
            score+=1;
        }
        option.disabled = true;//I want to make all option button disabled.
        console.log(score);
        scoreElement.textContent = `Score: ${score}`
    });
})

Array.prototype.map – How to handle unexpected behavior? [closed]

I have a select element with two options on a web page like so:

<select name="collections" id="select-collection">
          <option value="">--Please choose one--</option>
          <option value="coll-1">Collection 1</option>
          <option value="coll-2">Collection 2</option>
        </select>

When I select Collection 1, then select Collection 2, both work as expected. But if I then select Collection 1 again, it fails.

I traced the problem to this code:

export function getCollection(name) {
    let collection;
    if(name === "all"){
        collection = getAllProducts();
    } else {
        collection = collections[name];
    }
    const items = collection.items;
    const map = items.map((x) => getImage(x));
    collection.items = map;
    return collection;

Specifically, when this function is called for the third time, items.map((x) => getImage(x)) returns an array with all of its elements undefined. However, the map function isn’t the problem. The real cause occurs here:

    collection = collections[name];
    }
    const items = collection.items;

collection.items should be an array of strings. The strings are identifiers that are used to select images. On the third call, collection.items returns an array that has already been mapped! items.map((x) fails because, instead of a string identifier, x is a javascript object. Can anybody explain how this is possible?

How to update or remove the dragged image during drag & drop? [closed]

I am using SortableJS to implement a ranking system for users.

However, when I drag and drop an item (for example, moving rank 3 to rank 4), the image that follows the cursor does not update its background color to reflect the new rank.

The floating image (the one following the mouse) keeps the old background color instead of updating to match its new rank. I would like to either:

  • Update this floating image’s background color dynamically to reflect its new position.
  • Completely remove this floating image (so that only the ghost element remains in the list).

I’ve tried:

  • Using onMove to update styles dynamically → Did not affect the floating image.
  • Applying evt.item.style.backgroundColor inside onStart → Did not work as expected.
  • Attempting evt.originalEvent.dataTransfer.setDragImage(null, 0, 0) → This removes the image, but I want to confirm if this is the best way.

Screenshot for reference:

enter image description here

Mapbox search feature by lat lng

I want to search for a feature just like queryRenderedFeatures, but instead of providing viewport coordinates, providing geographical coordinates.

I tried to achieve this with map.project but it is giving me wrong results when map is pitched.

Thanks !