Strange issue when recursively concatenating to string

I have a JavaScript function which recursively calls the Spotify API in order to get data for a users saved songs such as track name, album, date added etc. (call limit is 50 so I need to repeat the call many times). It then manipulates the data into .csv format for the user to download. It is shown below (it works completely fine).

async function repeatGet(url, tracksArray = [["Track", "Artist", "Album", "Date-Time Added", "Spotify Link"]]) {

    tracksObject = await apiCall(url);
    for (track of tracksObject.items) { tracksArray.push([track.track.name, track.track.artists[0].name, track.track.album.name, track.added_at, track.track.external_urls.spotify]) }//tracksTotal.push(track) }

    if (tracksObject.next != undefined) { await repeatGet(tracksObject.next, tracksArray) }

    return tracksArray
}

tracksArray = await repeatGet("https://api.spotify.com/v1/me/tracks?limit=50")
console.log(tracksArray);

let csvData = "sep=t  n";
tracksArray.forEach(row => csvData += row.join("t") + "n")

console.log(csvData);

I tried to increase the efficiency by having the called data be turned into .csv format straight away and concatenating to a string (code below):

async function repeatGet(url, csvData = "sep=t  nTracktArtisttAlbumtDate-Time AddedtSpotifytLink") {
    
    tracksObject = await apiCall(url);
   
    for (track of tracksObject.items) {
        csvData += "n" + track.track.name + "t" + track.track.artists[0].name + "t" + track.track.album.name
        + "t" + track.added_at + "t" + track.track.external_urls.spotify;
    }
    // console.log(csvData)
    if (tracksObject.next != undefined) { await repeatGet(tracksObject.next, csvData) }

    console.log(csvData,csvData.length);
    return csvData;
}

csvData = await repeatGet("https://api.spotify.com/v1/me/tracks?limit=50");

For an unknown reason to me this code only returns the .csv string from the first api call (not the total string which is combined with all of the subsequent ones).

I’ve tried bugfixing by using console.log on certain parts and the code correctly appends to the csv as each new call is passed. However, after the final call all hell breaks loose and the console instantly returns all of the logs that happened as each subsequent call happened (with the csv string growing in size), but somehow in REVERSE order. Does anyone have any ideas? Thanks.

How do I make something function similar to this website without a backend? [closed]

The website I am trying to replicate is roblox-interstellar.vercal.app . I would like this to open a different link automatically via the proxy “interstellar” without using a backend.

Let me know if you find a solution!

Thank You.

I could not find any source code of the site. I want the site to open a link (of my choice) automatically with interstellar. (a web proxy)

Why does useState trigger rendering with the same value

As far as I know and read the official documentation, updates will only be triggered if the value is different.

The set function that lets you update the state to a different value and trigger a re-render.

However, after my testing in version 18.2, there is a situation that triggers repeated rendering.enter image description here

demo: https://playcode.io/1796380

I want to know what his capacity is and whether I need to be concerned about it

How to handle the states when disabling my component in react?

what I want is to make the TextPanel disabled if payStub has a value, and not be disabled if payStub does not have a value,

In my react code, I have the following:

    const [payStub, setPayStub] = useState(() => {
            if (isNewPayStub) {
                return get(user, 'stub', '');
            }
            return stubEdit.value?.name || '';
        }); 

const stubIsValid = Boolean(trim(payStub));

and in the react side I have the following:

return (
        <Panel
            onClose={onClose}
            onSave={handleSave}
            addNewText={isNewPayStub ? 'Add New PayStub' : ''}
        >
        
        ....
        
        <TextPanel
                    handleChange={setPayStub}
                    isValid={stubIsValid}
                    isRequired
                    label="Stub"
                    placeholder="Enter STUB"
                    value={payStub}
                />

The TextPanel receives a property of disabled , and when I add a property as disabled: {stubIsValid}, when the user enters the first character, the condition will be met and it makes the TextPanel disabled which is not what I want (user should be able to fill enter the payStub) .
How do I fix this situation?

Styling the ::before element on a mat-expansion-panel-header?

In this demo I’m trying to style the mat-expansion-panel-header‘s ::before pseudo element like this (Style rules added to styles.scss):

mat-expansion-panel-header {
  position: relative;
}

mat-expansion-panel-header::before {
  content: '';
  position: absolute;
  top: 0px;
  left: 0px;
  bottom: 0px;
  right: 0px;
  z-index: 1000;
  background-color: black;
}

So if the above rule would take effect the mat-expansion-panel-header items in the demo would just be black.

However the rule does not take effect and when I look in the developer tools I don’t see the ::before element.

Any ideas on how to fix this?

React useEffect not running after all DOM has loaded

I have a react Application where I am trying to add the AWS Chat Widget.

It is working but I want to add some additional styling to the launch icon which doesnt seem to be their out of the box – https://docs.aws.amazon.com/connect/latest/adminguide/customize-widget-launch.html

I want too add a tool tip as I have mocked up in the image:

enter image description here

This is the code I have added to useEffect method:

  useEffect(() => {
    const widgetEle =  document.getElementById('amazon-connect-chat-widget');
    debugger;
    if (widgetEle) {
      widgetEle.innerHTML = '<span class="tooltip-text" id="left">Chat with us!<button id="chatToolTipClose" type="button" class="close">x</button></span>';
    }
 }, []);

I thought this should only run after the DOM has fully rendered – but on my debugger the widgetEle is always null. But when I run the exit the debugger the default google chat icon is displayed – and when I inspect the element I can see there is no typo in the id – it is exactly what I specify.

Is there something I am missing?

Can’t Log into Strapi after Accidentally Setting User to ‘Active False’

On the Strapi application, I accidentally checked the ‘active false’ box for the user when it should have been ‘true.’ Since then, I can’t log in to Strapi. I’m convinced that to fix this issue, I need to go into the database, but I can’t find which file I should modify to change my user’s status back to ‘active true.’

Database: SQLite

Language: JavaScript

I tried to back up an old version on GitHub, but no success…

I also tried to filter all active elements in VS Code, but I can’t figure out which one I should fix.

Put a for loop iteration in a Bootstrap group list button click

I have a lab about addEventListener, where in a click of a button shows your for loop with office locations.

const grupList = document.querySelector("ul");
console.log(grupList);

const listItems = document.querySelector("li");
console.log(listItems);`

const offices = document.getElementById("ofLocations");


let officeLocations = ["New York", "London", "Paris", "Tokyo", "Sydney"];



```function getOfficeLocations (arr){
 ``` for (let i = 0; i < arr.length; i++) {
    `console.log(arr[i]);
```offices.addEventListener("click",  getOfficeLocation {

})
  }
}
`getOfficeLocation(officeLocations);`

This is what I have done so far.

Multiple different textures/materials on 3D heightmap

over the weeks I have created a chunked infinite heightmap terrain. The chunk system is very simple and is not the topic of this question. The topic of this question is how to create a terrain heightmap with the possibility of blending between different textures/materials (grass, dirt, sand, etc.) smoothly.

A chunk is basically a grid of height values and texture values (so 0 is dirt, 1 is grass, 2 is something else). Then I generate the chunk mesh by taking all those values and turning them into vertex attributes (height is a buffer object and so is the texture/material; I only pass the height because I calculate the X and Z position in the shader).

Now, the vertex shader looks like this:

  #version 300 es
  layout (location = 0) in float height;
  layout (location = 1) in float material;

  out float h;
  out float m;
  out vec2 uv;
  
  uniform vec4 chunkPosition;
  uniform int chunkSize;
  uniform mat4 view, projection;

  void main () {
    int col = gl_VertexID % (chunkSize + 1);
    int row = gl_VertexID / (chunkSize + 1);
    vec4 position = vec4 (col, height, row, 1.0);
  
    gl_Position = projection * view * (chunkPosition + position);
    uv = vec2 (float (col) / float (chunkSize), float (row) / float (chunkSize));
    h = height;
    m = material;
  }

And the fragment shader looks like this:

  #version 300 es
  precision lowp float;

  in vec2 uv;
  in float h;
  in float m;
  out vec4 color;

  uniform sampler2D grass, drygrass, dirt;
  
  void main () {
    vec4 grs = texture (grass, uv);
    vec4 drt = texture (dirt, uv);
  
    color = mix (grs, drt, m);
  }

With the single value m representing the material at a given vertex I seem to be able to sucessfuly blend between two textures and it looks great. However, I can’t wrap my head around how to implement more textures here (in this example, how to make it so drygrass is also on the terrain).

I understand that the way it works here is it does a weighed average and interpolated between the grass and dirt materials based on the value m (which for now I have not made it go beyond 1).

I already tried making it so the value does go to 2 (so in this example it could be e.g. drygrass) but I find it hard to figure out how to mix it all.

Is the way to go to have a different “m” value for every single texture type in the terrain?

autofill html form w/ multiple different fields, including: Checkbox and Dropdown selections

Part of the html form I want to autofill:

<div h2 class="display-6 text-uppercase mb-3">
   Service</h2>
   <span class="question">Select Service(s):</span><br>
   <input type="checkbox" id="car_wash" name="car_wash" value="car_wash"/>
   <label for="car_wash"> Car Wash</label><br>
   <input type="checkbox" id="window_cleaning" name="window_cleaning" value="Window Cleaning" autocomplete="name">
   <label for="window_cleaning"> Window Cleaning</label><br>
   <input type="checkbox" id="power_wash" name="power_wash" value="Power Wash" autocomplete="name"
   <label for="power_wash"> Powerwashing</label><br>
   <input type="checkbox" id="curb_address" name="curb_address" value="Curb Address Painting" autocomplete="name"
   <label for="curb_address"> Curb Address Painting</label><br>
</div>
<div id="dropdownHolder" class="col-lg-12 mb-3">
   <select id="carwash_type" name="carwash_type" class="form-select form-control" aria-label="Default select example" value="ON">
      <option selected> Car Type</option>
      <option value="1">Coupe / Sedan / Hatchback</option>
      <option value="2">Suv / Crossover</option>
      <option value="3">Mini Van</option>
      <option value="4">Pickup Truck</option>
      <option value="5">I'm not sure</option>
   </select>
</div>
<div id="dropdownHolder" class="col-lg-12 mb-3">
   <select id="carwash_type" name="carwash_type" class="form-select form-control" aria-label="Default select example" value="ON">
      <option selected> Car Wash Package</option>
      <option value="1">Express Interior</option>
      <option value="2">Express Exterior</option>
      <option value="3">Full Service Wash</option>
   </select>
</div>

There are several pages linking to this form, each of which have a service selected and if it’s a car wash, the extras as well, including car type and wash package.

Here is the html of the car wash selection – before the form page, trying to link to it w/autofilled selections.

<div class="services-content text-center border py-3 py-md-5 px-3">
   <iconify-icon class="service-icon"
      icon="fa6-solid:car-on"></iconify-icon>
   <h4 class="my-3">Auto Detailing</h4>
   <a href="booking.html" class="icon-link my-3">
      Book Now 
      <iconify-icon
         icon="tabler:arrow-right" class="arrow-icon"></iconify-icon>
   </a>
</div>

From what I’ve found out, there are several ways to do this. I’m still very new and I’m just not sure how to go about this the most reliable way. If needed maybe with js?

Failed loading pdf, getting error failed loading worker using React-PDF, Mantine Dropzone

My goal is to have a user upload a PDF file and preview it using React-PDF. I am using Mantine’s Dropzone for file upload and loading the file into preview using React-pdf.

The issue is that I am failing to load the pdf file and getting error

Error: Setting up fake worker failed: "Cannot load script at: http://localhost:5173/pdf.worker.js".

My code:

import { useState, useRef, useEffect } from 'react';
import { Document, Page } from 'react-pdf';
import { Button, Group } from '@mantine/core';
import { Dropzone, PDF_MIME_TYPE } from '@mantine/dropzone';

type PDFFile = string | File | null;

const FileDropzone = () => {
  const dropzoneOpenRef = useRef<() => void>(null);
  const [file, setFile] = useState<PDFFile>(null);

  const onFileChange = (files: File[]) => {
    if (files && files[0]) {
      setFile(files[0]);
    }
  };

  useEffect(() => {
    console.log(file);
  }, [file]);

  return (
    <>
      <h1>React Drop File</h1>
      <p>Click on the Vite and React logos to learn more</p>
      <Dropzone
        openRef={dropzoneOpenRef}
        onDrop={onFileChange}
        onReject={(file) => console.log('Rejected files', file)}
        maxSize={5 * 1024 ** 2}
        accept={PDF_MIME_TYPE}>
        <Group justify='center' mt='md'>
          <Button onClick={() => dropzoneOpenRef.current?.()}>
            Select Files
          </Button>
        </Group>
      </Dropzone>

      <div>
        <Document file={file} onLoadError={console.error}>
          <Page pageNumber={1} />
        </Document>
      </div>
    </>
  );
};

export default FileDropzone;

Can you automatically extract React components from JSX?

I’m working on a React translation of a website exported from a design tool called Webflow. The export contains the html and css I need to create the page. I’ve found a tool to translate the HTML into React, but now I want to turn segments of the translated code into components automatically in a similar way.

There are two tools I’ve found to do this:

  1. Glean,
  2. VScode Refactor

They both allow you to turn a snippet of JSX into a component within the same module, but they don’t automatically use the <Component></Component> syntax, they can’t be named on creation, and they don’t allow you to spin out that snippet into a new file. All of which are features I would really like.

Are these the only two options for automatically generated react Components? Or is there a better way?

Capacitor doesn’t work for Ionic with vanilla JS

When creating Ionic app following documentation https://ionicframework.com/docs/vue/quickstart and converting typescript to javascript (10 steps on this doc page), then there is a problem creating android version by running this command: ionic cap add android

This command should create android folder, but i get this error message:

enter image description here

This error doesn’t exist if application is set for typescript, it appears only after converting to javascript.

Seems this is an internal issue with capacitor. Is there a way to fix this via vite.config or something similar?

By the way it’s Ionic version 7

React-Native Expo-Go app: ‘Not a valid React component’ error

I am trying to develop my first proper React-Native app and I’m having trouble straight out the gate. I am trying to use a few different imported Navigation libraries (BottomTabNavigator, NativeStackNavigator, Stack.Screen, etc.).

I am getting an error when I run the app on Expo-Go saying something like “Error: Got an invalid value for ‘component’ prop for the screen ‘ManageExpense’. It must be a valid React Component.”
So far a I have App.js, and 3 screens, AllExpenses.js, ManageExpense.js, and RecentExpenses.js.
I’ll post them in that order below.

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

//importing custom components
import ManageExpense from './screens/ManageExpense';
import RecentExpenses from './screens/RecentExpenses';
import AllExpenses from './screens/AllExpenses';

const Stack = createNativeStackNavigator();// this stack will create an object that gives access to 2 components (nav, register screens): https://reactnavigation.org/docs/native-stack-navigator
const BottomTabs = createBottomTabNavigator(); // allows bottom tab navigation: npm install @react-navigation/bottom-tabs

//this function handles the bottom tab navigator
function ExpensesOverview() {
  return (
    <BottomTabs.Navigator>
      <BottomTabs.Screen name="RecentExpenses" component={RecentExpenses} />
      <BottomTabs.Screen name="AllExpenses" component={AllExpenses} />
    </BottomTabs.Navigator>
  );
}

export default function App() {
  return (
    <>
      <StatusBar style="auto" />
      {/* setting up navigation */}
      <NavigationContainer>
        {/* StackNavigator allows me to dynamically load the tabs options based on which screen is selected*/}
        <Stack.Navigator>
          {/* below uses the custom function above to display both options in one stack.screen */}
          <Stack.Screen name="ExpensesOverview" component={ExpensesOverview} />
          <Stack.Screen name="ManageExpense" component={ManageExpense} />
        </Stack.Navigator>
      </NavigationContainer>
    </>
  );
}


import React from 'react';
import { Text } from 'react-native';

export default function AllExpenses() {

    return <Text>AllExpenses Screen</Text>

}
import React from 'react';
import { Text } from 'react-native';

export default function ManageExpense() {

    return <Text>ManageExpense Screen</Text>

}


import React from 'react';
import { Text } from 'react-native';

export default function RecentExpenses() {

    return <Text>RecentExpenses Screen</Text>

}

I’m trying to get the imported navigation components to work properly. I really can’t spot where I’m going wrong I’ve been looking at it for a while and even ChatGPT can’t seem to spot it… Any help would be appreciated. Thanks.

Why doesn’t my mobile menu open anymore ever since I’ve added some new script?

Ever since I’ve added the color-choice script, my hamburger menu isn’t working anymore. I don’t know what is in conflict but the only thing that happens when I click on the hamburger menu is that I get a notification ‘Javascript:void(0)’. Can anyone help me figure this problem out? Of course I need the mobile menu to work before I can launch my website, but I also really want to keep my color choice script because I think that’s a cool feature. Hope someone can help me out.

$(window).on("load", function () {

    "use strict";

/* ===================================
        Loading Timeout
 ====================================== */
$('.side-menu').removeClass('hidden');

    setTimeout(function(){
        $('.preloader').fadeOut();
    }, 1000);
});

jQuery(function ($) {

    "use strict";

/* ===================================
    Side Menu
====================================== */

if ($("#sidemenu_toggle").length) {
    $("#sidemenu_toggle").on("click", function () {
        $(".side-menu").removeClass("side-menu-opacity");
        $(".pushwrap").toggleClass("active");
        $(".side-menu").addClass("side-menu-active"), $("#close_side_menu").fadeIn(700)
    }), $("#close_side_menu").on("click", function () {
        $(".side-menu").removeClass("side-menu-active"), $(this).fadeOut(200), $(".pushwrap").removeClass("active");
        setTimeout(function(){
            $(".side-menu").addClass("side-menu-opacity");
        }, 500);
    }), $(".side-menu .navbar-nav .nav-link").on("click", function () {
        $(".side-menu").removeClass("side-menu-active"), $("#close_side_menu").fadeOut(200), $(".pushwrap").removeClass("active");
        setTimeout(function(){
            $(".side-menu").addClass("side-menu-opacity");
        }, 500);
    }), $("#btn_sideNavClose").on("click", function () {
        $(".side-menu").removeClass("side-menu-active"), $("#close_side_menu").fadeOut(200), $(".pushwrap").removeClass("active");
        setTimeout(function(){
            $(".side-menu").addClass("side-menu-opacity");
        }, 500);
    });
}

/* ===================================
    Bottom Nav Appear
====================================== */

$(function () {
    var $win = $(window);
    jQuery(function($) {
        $(window).scroll(function() {
            if($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
                // alert("near bottom!");
                $('.sidenav-bottom').css('opacity','1');
                $('.sidenav-bottom').addClass('sidenav-bottom-fixed');
            }
            if($(window).scrollTop() + $(window).height() < $(document).height() - 300 && $(window).scrollTop() + $(window).height() > $(document).height() - 400 )  {
                $('.sidenav-bottom').css('opacity','0');
                $('.sidenav-bottom').removeClass('sidenav-bottom-fixed');
            }
        });
    });
});

if ($(window).width() <= 991) {
    $(".scroll").on("click", function (event) {
        event.preventDefault();
        $('html,body').animate({
            scrollTop: $(this.hash).offset().top - 40
        }, 200);
    });
}

/* ===================================
    Header Appear
====================================== */

$(window).on('scroll', function () {
    if ($(this).scrollTop() > 260) { // Set position from top to add class
        $('.sidenav-bottom').css('opacity','0');
        $('header .inner-header').addClass('header-appear');
    }
    if($(this).scrollTop() < 260) {
        $('.sidenav-bottom').css('opacity','1');
        $('header .inner-header').removeClass('header-appear');
    }
});

/*===================================
    Go Top Scroll
====================================== */
$(function(){
    // Scroll Event
    $(window).on('scroll', function(){
        var scrolled = $(window).scrollTop();
        if (scrolled > 260) $('.go-top').addClass('active');
        if (scrolled < 260) $('.go-top').removeClass('active');
    });
    // Click Event
    $('.go-top').on('click', function() {
        $("html, body").animate({ scrollTop: "0" },  100);
    });
});

/* ===================================
    Portfolio Carousel
====================================== */

$('.portfolio-carousel').owlCarousel({
    loop:true,
    margin:10,
    slideSpeed: 5000,
    slideTransition:'linear',
    nav:false,
    dots:false,
    autoplay:false,
    autoplayTimeout:8000,
    autoplayHoverPause:false,
    responsive:{
        0:{
            items:1
        },
        600:{
            items:1
        },
        1000:{
            items:1
        },
    }
});

$('.portfolio-right-arr').click(function() {
    var owl = $('.portfolio-carousel');
    owl.owlCarousel();
    owl.trigger('next.owl.carousel');
});
$('.portfolio-left-arr').click(function() {
    var owl = $('.portfolio-carousel');
    owl.owlCarousel();
    owl.trigger('prev.owl.carousel');
});

/* ===================================
    Banner Carousel
====================================== */

$('.slider-carousel').owlCarousel({
    loop: true,
    margin: 10,
    slideSpeed: 9999,
    slideTransition: 'linear',
    nav: false,
    dots: false,
    autoplay: true,
    smartSpeed: 450,
    autoplayTimeout: 3000,
    autoplayHoverPause: false,
    responsive:{
        0:{
            items:1
        },
        600:{
            items:1
        },
        1000:{
            items:1
        },
    }
});

/* ===================================
    Testimonial Carousel
====================================== */

$('.review-carousel').owlCarousel({
    loop:true,
    margin:10,
    slideSpeed: 5000,
    slideTransition:'linear',
    nav:false,
    dots:false,
    autoplay:false,
    autoplayTimeout:8000,
    autoplayHoverPause:true,
    responsive:{
        0:{
            items:1
        },
        600:{
            items:1
        },
        1000:{
            items:1
        },
    }
});

/* ===================================
     Wow Effects
======================================*/

var wow = new WOW(
    {
        boxClass:'wow',      // default
        animateClass:'animated', // default
        offset:0,          // default
        mobile:false,       // default
        live:true        // default
    }
);
    wow.init();
});

$(document).ready(function() {
    // Toon de kleurkeuze pop-up bij het laden van de pagina
    setTimeout(function() {
        $("#color-choice-popup").fadeIn();
        $("#color-choice-overlay").fadeIn(); // Laat ook de overlay zien
        $("body").addClass("no-scroll"); // Voeg een klasse toe om scrollen te voorkomen
    }, 1500);

    // Functie om de themaklasse van de website aan te passen
    function updateThemeClass(themeClass) {
        document.documentElement.className = themeClass; // Stel de klasse van het root element in
    }

    // Event listener voor kleurkeuze
    $(".color-choice").on("click", function() {
        var themeClass = $(this).data("theme");
        updateThemeClass(themeClass); // Pas de themaklasse aan met de gekozen klasse
        $("#color-choice-popup").fadeOut(); // Verberg de pop-up
        $("#color-choice-overlay").fadeOut(); // Verberg ook de overlay
        $("body").removeClass("no-scroll"); // Verwijder de klasse om scrollen mogelijk te maken
    });

    // Controleer of de kleurindicator al bestaat om te voorkomen dat deze meerdere keren wordt toegevoegd
    if($("#color-indicator-menubar").length === 0) {
        // Zorg ervoor dat dit geplaatst wordt in het juiste header-element, naast de Get a Quote knop
        $("<div id='color-indicator-menubar'></div>")
            .insertBefore(".inner-header .row .col-lg-4.d-flex.justify-content-end .btn-main");
    }

    // Laat de kleurkeuzepopup opnieuw zien wanneer op de kleurindicator wordt geklikt
    $("#color-indicator-menubar").on("click", function() {
        $("#color-choice-popup").fadeIn();
        $("#color-choice-overlay").fadeIn(); // Laat ook de overlay zien
        $("body").addClass("no-scroll"); // Voeg een klasse toe om scrollen te voorkomen
    });
});