Touche event in react-native FlatList not working if item was deleted and readded

I’m doing an app on android using react-native and I have a problem using touche input within my FlatList after removing and adding element to the FlatList.

How the problem happens :

  1. I add one element in my data array and it adds a Button to the FlatList.
  2. I can interact with the Button as expected.
  3. I reset the data array to [].
  4. It removes the Button from the FlatList.
  5. I add another element in my data array and it adds a Button to the FlatList
  6. (PROBLEM start here) even tho the Button appears in the FlatList, I can’t interact with it (I’ve tried other touchable elements like Pressable, TextInput or just using an onPress on an element and I get the same behavior)
  7. If I add another element to the data array, it will add a new working Button (i.e. first Button not working but second Button working)
  8. If I delete n Button and start adding n + m Button again, Then the first n would not work but the m-th last would work.

I reduced the problem to the following small code :

import React, {useState} from 'react';
import {Button, FlatList, View} from 'react-native';

export default function Test() {
  const [data, setData] = useState([]);

  function addData() {
    setData(prev => [...prev, {key: new Date().getTime(), text: 'some text'}]);
  }

  function deleteAllData() {
    setData([]);
  }

  return (
    <View
      style={{
        flex: 1,
      }}>
      <Button title={'ADD'} onPress={() => addData()} />
      <Button title={'DEL'} onPress={() => deleteAllData()} />
      <FlatList
        data={data}
        renderItem={({item, index}) => {
          return (
            <Button
              key={item.key}
              title={`${item.key}`}
              onPress={() => console.log('Clic!')}
            />
          );
        }}
      />
    </View>
  );
}

I think I’m missing something obvious but it’s driving me crazy^^ Any help would be appreciated !

I’m using react-native 0.66.0 and react 17.0.2 testing on my physical android device.

“Child_Process” function Exec hanging on Windows

Before I get bashed for using Guilded over Discord, that isn’t the point of this question. Also, yes this is a Client Mod for Guilded, for which we have been given permission by Guilded to program.

The issue is closing the software, before messing with the files and the opening once we’ve finished the process. Two issues come from both exec commands, I’ve tried solutions I found on other questions, but none were successful, I also tried awaiting SpawnSync, with a callback, no dice.

// Close Guilded, then continue, because we need to make sure Guilded is closed for the new injection.
exec(platform.close).on("exit", () => {
    // Creates path for ReGuilded
    const reguildedPath = resolve(dir || join(process.env.APPDATA || process.env.HOME, ".reguilded"));

    tasks[taskArg](platform, reguildedPath, elevator)
        .then(() => {
            console.info(
                "Relaunching Guilded (If not opened in 10 minutes after this please manually execute the app)"
            );

            // Open the app Again after the injection task is done
            exec(platform.open).on("exit", () => {
                process.exit();
            });
        })
        .catch(err => {
            console.error("Failed to do task", taskArg, ":", err);
        });
});
// platform.close
// Linux: "killall guilded"
// Darwin: "killall Guilded"
// Win32: "taskkill /f /IM Guilded.exe >nul"

// platform.open
// Linux: "/opt/Guilded/guilded& disown"
// Darwin: "/Applications/Guilded.app"
// Win32: join(process.env.LOCALAPPDATA, "Programs/Guilded/Guilded.exe") + " >nul"

All these commands do launch & close Guilded successfully, but the issue lies in the shell, not closing/returning primarily on Windows.

The code is TS at source but gets compiled into JS. Any help or pointers would be helpful. We’re using the latest LTS of Node, and are looking for 100% cross-compatibility.

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘data’)

I’m building out CRUD functionality and create had worked the other day with the same code in the component, but now it is giving an error:

Unhandled Rejection (TypeError): Cannot read properties of undefined (reading ‘data’)

I’m getting an error with the validations, and not sure if it has to do with props. Here is the code where the error exists:

> 30 |     const errorResponse = err.response.data.errors;
     | ^  31 |     const errorArr = [];
  32 |     for (const key of Object.keys(errorResponse)) {
  33 |         errorArr.push(errorResponse[key].message)```

Is anyone familiar with this issue and knows how to fix it?

Reactjs cannot set properties of null (setting ‘currentTime’) [duplicate]

I am trying to solve front-end development libraries projects using React from Freecodecamp.

In Drum Machine App, I am able to replicate almost all the functions but there is a bug and I am not able to identify that.

So, there are 2 set of sounds and there is a checkbox. When checkbox is not checked(default) Set 1 Sounds are played and when checkbox is checked Set 2 sounds are played.

There are 2 ways sounds are generated. By mouse click and by key press[Q,W,E,A,S,D,Z,X,C].

The problem is when the checkbox is checked and I’m trying to generate sound by key press only [C,D] are working rest are showing error cannot set properties to NULL. When checkbox is unchecked all keydown event are working properly.

This is the problem statement : https://www.freecodecamp.org/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-drum-machine

And here is my code:

App.js

import "./styles.css";
import React, { useState, useEffect } from "react";
import { bankOne, bankTwo } from "./Sounds";
import ReactFCCtest from "react-fcctest";

const KeyboardKey = (props) => {
  const handleKeyDown = (e) => {
    if (e.keyCode === props.sound.keyCode) {
      props.play(props.sound.id, props.volume, props.power);
    }
  };

  useEffect(() => {
    document.addEventListener("keydown", handleKeyDown);
  }, []);

  return (
    <button
      className="drum-pad"
      id={props.sound.keyTrigger}
      onClick={() => props.play(props.sound.id, props.volume, props.power)}
    >
      <audio className="clip" id={props.sound.id} src={props.sound.url} />
      {props.sound.keyTrigger}
    </button>
  );
};

const Keyboard = (props) => {
  return props.sounds.map((sound) => (
    <KeyboardKey
      play={props.play}
      sound={sound}
      power={props.power}
      volume={props.volume}
    />
  ));
};

export default function App() {
  const [power, setPower] = useState(true);
  const [bank, setBank] = useState(false);
  const [volume, setVolume] = useState(0.5);
  const [sounds, setSounds] = useState(bankOne);
  const [soundName, setSoundName] = useState("");

  const play = (key, volume, power) => {
    if (power) {
      setSoundName(key);
      console.log(key);
      const audio = document.getElementById(key);
      console.log(audio);
      console.log(volume);
      audio.currentTime = 0;
      audio.volume = parseFloat(volume);
      audio.play();
    }
  };

  const handleVolumeChange = (e) => {
    if (power) {
      setVolume(e.target.value);
    }
  };

  const handleBankChange = (e) => {
    if (power) {
      setBank(!bank);
      setSounds(e.target.checked ? bankTwo : bankOne);
    }
  };

  const handlePowerChange = (e) => {
    setPower(!power);
  };

  return (
    <>
      <ReactFCCtest />
      <div id="drum-machine">
        <div id="display"></div>
        <Keyboard play={play} sounds={sounds} volume={volume} power={power} />
        {power && (
          <>
            <p>Bank</p>
            <label className="switch">
              <input
                type="checkbox"
                defaultChecked={bank}
                onChange={(e) => handleBankChange(e)}
              />
              <span className="slider rounded" />
            </label>
            <p>{soundName}</p>
            <h3>Volume: {Math.round(volume * 100)} %</h3>
            <input
              max="1"
              min="0"
              type="range"
              step="0.01"
              value={volume}
              onChange={(e) => handleVolumeChange(e)}
            />
            <br />
          </>
        )}
        <p>Power</p>
        <label className="switch">
          <input
            type="checkbox"
            defaultChecked={power}
            onChange={(e) => handlePowerChange(e)}
          />
          <span className="slider rounded" />
        </label>
      </div>
    </>
  );
}

Sounds.js

export const bankOne = [
  {
    keyCode: 81,
    keyTrigger: "Q",
    id: "Heater-1",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"
  },
  {
    keyCode: 87,
    keyTrigger: "W",
    id: "Heater-2",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3"
  },
  {
    keyCode: 69,
    keyTrigger: "E",
    id: "Heater-3",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3"
  },
  {
    keyCode: 65,
    keyTrigger: "A",
    id: "Heater-4",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3"
  },
  {
    keyCode: 83,
    keyTrigger: "S",
    id: "Clap",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3"
  },
  {
    keyCode: 68,
    keyTrigger: "D",
    id: "Open-HH",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3"
  },
  {
    keyCode: 90,
    keyTrigger: "Z",
    id: "Kick-n'-Hat",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3"
  },
  {
    keyCode: 88,
    keyTrigger: "X",
    id: "Kick",
    url: "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3"
  },
  {
    keyCode: 67,
    keyTrigger: "C",
    id: "Closed-HH",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3"
  }
];

export const bankTwo = [
  {
    keyCode: 81,
    keyTrigger: "Q",
    id: "Chord-1",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3"
  },
  {
    keyCode: 87,
    keyTrigger: "W",
    id: "Chord-2",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3"
  },
  {
    keyCode: 69,
    keyTrigger: "E",
    id: "Chord-3",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3"
  },
  {
    keyCode: 65,
    keyTrigger: "A",
    id: "Shaker",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3"
  },
  {
    keyCode: 83,
    keyTrigger: "S",
    id: "Open-HH",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3"
  },
  {
    keyCode: 68,
    keyTrigger: "D",
    id: "Closed-HH",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3"
  },
  {
    keyCode: 90,
    keyTrigger: "Z",
    id: "Punchy-Kick",
    url: "https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3"
  },
  {
    keyCode: 88,
    keyTrigger: "X",
    id: "Side-Stick",
    url: "https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3"
  },
  {
    keyCode: 67,
    keyTrigger: "C",
    id: "Snare",
    url: "https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"
  }
];

PS: Some of my code is from a Tutorial.

adding and subtracting a string-number works differently in javascript

HTML

<body>
    <h1>Counter</h1>
    <p id="num">0</p>
    <div>
        <button id="minus">-</button>
        <button id="plus">+</button>
    </div>
    <script src="src/main.js"></script>
</body>

JS

const num = document.getElementById('num')
const minus = document.getElementById('minus')
const plus = document.getElementById('plus')

minus.addEventListener('click', () => {
  num.textContent -= 1;
})

plus.addEventListener('click', () => {
  num.textContent += 1;
})

This is a simple counter app. If I press minus btn, it acts as expected (i.e. subtracts 1 from number)
But if I press plus, I get a string concatenation (i.e. ’01’)

I’m confused here. Why one acts like a number and the other string? it seems like there is a auto-conversion of type in very inconsistant way.

and what would be the best practice to fix ‘plus’?

Why regex matches when tested but not being captured in String replacement

I am trying to perform the following String replacement via regex.

This is the String.

let originalStr = 'localhost:3000/sample/prospect/card/intl/name?ref=-huNn';

I am replacing the String via following implementation where I am calling 2 different regex replacements on the original string.

// this works 
originalStr = originalStr.replace(`/name`, `/${router.location.query.ref}`); 

// This is the issue. Not replacing. 
// There is an OR in this regex cos I want to replace even if there is no `/card` in the String.
originalStr = originalStr.replace(//prospect/card/|/prospect//, '/prospect/cards/'); 

This is the current updated String.

localhost:3000/sample/prospect/card/intl/-huNn?ref=-huNn

I was expecting it to be the following:

localhost:3000/sample/prospect/cards/intl/-huNn?ref=-huNn // cards instead of card

When tested via https://regex101.com/, the regex is capturing the value correctly.

But in code. the replacement is not happening. What am I doing wrong with this regex?

Reset localstorage variable at specific time

How do I reset a localStorage variable that is a boolean that tracks whether a user has completed an action that day. When the time reaches, for example, 8 am local time, it resets the boolean to false to show that the action hasn’t been completed yet.

If the user has completed the action that day, the localStorage variable gets set to true and we show the countdown to 8 am.

Here are my methods that check for current time and time until 8 am.

const twoDigits = (number) => {
    return (number < 10 ? '0' : '') + number;
}

const countDown = () => {
    var reset = new Date();
    var now = new Date();
    reset.setHours(8, 0, 0);
    if(now > reset){
        reset.setDate(reset.getDate() + 1);
    }

    var timeToReset = ((reset - now) / 1000);

    var hours = ~~(timeToReset / 60 / 60) % 60;
    var minutes = ~~(timeToReset / 60) % 60;
    var seconds = ~~timeToReset % 60;

    return `${twoDigits(hours)}:${twoDigits(minutes)}:${twoDigits(seconds)}`;
}

const intervalId = setInterval(() => {
  console.log(countDown());
}, 1000);

// clear interval after 10 seconds so its not running indefinitely
setTimeout(() => {clearInterval(intervalId)}, 10000);

How to find duplicate values in object and push in array to create distinct array of objects in Angular8

I am getting below response from API, but i want to format it for iteration to reach the correct values.

In below objects, i am getting column makeLineName and based on this column, i want to create one types array and push whole object as it is on types array.

Suppose for ex – In below response, We have 2 objects for “makeLineName”:”Red”, So i want to create one types array and push all object inside types array whose matching makeLineName = Red. Thats it.

const data = [{
"makeLineName":"Red",
"country":"Germany",
"processTypeId":"3",
"processTechType":"Batch & crunch"
},
{
"makeLineName":"Red",
"country":"Germany",
"processTypeId":"3",
"processTechType":"Batch"
},
{
"makeLineName":"Blue",
"country":"India",
"processTypeId":"3",
"processTechType":"Continues"
}
];

Expected Output

const data = [{
"makeLineName":"Red",
"country":"Germany",
types :[{
"makeLineName":"Red",
"processTypeId":"3",
"country":"Germany",
"processTechType":"Batch & crunch"
},
{
"makeLineName":"Red",
"processTypeId":"3",
"country":"Germany",
"processTechType":"Batch"
}]
},
{
"makeLineName":"Blue",
"country":"India"
types :[{
"makeLineName":"Blue",
"country":"India",
"processTypeId":"3",
"processTechType":"Continues"
}

}];

I did below code, it was working fine, but it is creating many nested arrays for types and because of this i am facing issue in iterating with loop to get the perfect value of types array.

getMakeLineMasterData() {
    const data = {
      data1: 'India'
    };  
    this.testfile.getWork(data).pipe(map(data => this.processData(data))).subscribe((resp: any) => {
      if (resp) {
        console.log(this.dataSource, "resp");
      }
    });
  }
  processData(data: any) {
    let mappedData = [];
    for (const item of data) {
      const mitem = mappedData.find(obj => obj.makeLineName == item.makeLineName);
      if (mitem) {
        mitem['types'].push(item);
      } else {
        let newItem = item;
        newItem['types'] = [item];
        mappedData.push(newItem);
      }
    }   
    return mappedData;
  }

Right now my code is working and returning data but it is creating many nested arrays for types inside and inside likewise..
Can anyone help me to make it proper as per my expected output.

javascript global variable undefined when calling inside the new, additional function

Coding linting with JS to iterate through a text.
I have a few iterations that count a specific conditions, for example
sentences
are set to be added upon when there is ‘.’ or ‘!’.

However, when I created a function that would print one string with information about number of sentences, overused words and so on, it shows up as undefined… Here’s a piece of code

console.log(betterWords.length);
let counter = 0;

for (let i = 0; i < betterWords.length; i++){
  if (betterWords[i] === 'really' || betterWords[i] === 'very' || betterWords[i] === 'basically'){
    counter++
}
}
console.log('You used overused words ' + counter + ' times.');

let sentences = 0;

betterWords.forEach (word => {
  if (word[word.length-1] === '.' || word[word.length-1] === '!'){
    sentences++
}
});

console.log('There are ' + sentences + ' sentences');
numberOfWords = betterWords.length;

const printFunction = (betterWords, counter, sentences) => {
  return('The number of words in text is ' + numberOfWords + ' There are ' + sentences + ' and overused words are used ' + counter + ' times.');
};

console.log(printFunction());

Output
182
You used overused words 8 times.
There are 12 sentences
The number of words in text is 182 There are undefined and overused words are used undefined times. I am mentioning sentences as one example here. One can see that numberOfWords give a proper output

As one can see once sentences return 12, the other time it’s undefined.

How to make in Cypress an equivalent of PressKeyCode from Appium?

Today i meet a problem with a particular input, it looks like that :

enter image description here –> enter image description here

The problem with this input is that it’s an input with 6 input in it, so a typical cy.get('element').type(aValue) is not working.
I tried to loop on each of the 6 inputs, but it’s not working either.

It seem that the value are not writed like it should be on other normal input (like a textArea) but it show me a “click” on each input.
(This solution : cy.get('element').invoke('val', aValue) doesn’t work either but it show the number on each input but disappear when i want to validate the entry)

Before using Cypress, i was using Appium and i was just looping like that driver.pressKeyCode(charValue) over the value (i didn’t select any element to press the code like it could be here : https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) and it worked fine.

But right now this solution doesn’t work with Cypress. Or i just don’t understand how this solution https://sqa.stackexchange.com/a/46913 works, i tried different behaviour and nothing worked for my particular case.

Anyone have an idea to overpass this problem with my input or any solution to make the same thing as i did with Appium ?

What string method for matching specific strings in Javascript

This might be a simple duplicate question but I couldn’t find any solution that resolve my case below. Please help me out! 🙂

TL;DR:

I’m looking for a string method to check if the value matches a specific string and return that result.

I have 3 values which are strings: "$", "$$" and "$$$"

Currently using the .includes method and not getting the result I want. It includes all the results that contain a character from the string -> I only want them to return the results with exactly the value of strings above.

Please check SearchFilter.js component code below.

Ex: If a user chooses “$” from the priceDropdown, it will only return
the dishes with priceRange = “$”.

Explain:

  • Inside this Dinner.js, I have a foodList state which is an array that contains all of the data of food from a MongoDB collection (foodName, isVegetarian, priceRange).

  • And a Search.js component which has: a search input for foodName, a dropdown for priceRange, a dropdown for isVegetarian option.

If a user searches for the text: “pasta”, price range option: “$$”,
vegetarian option: “yes”.

  • It will filter from the foodList array and only return the dishes with those choices included.

-> The problem is in how I’m currently returning the value from the data’s priceRange that includes the value from the priceDropdown that the user chose.

  • If they choose “$” from the priceDropdown, it will return all the results with “$” included (including “$$” and “$$$” options).

  • If they choose “$$” value from the dropdown, it will return the results of “$$” and “$$$


**Question:**

What string method to use to make it only return the results with the right specific string?

Ex: If a user chooses “$” from the priceDropdown, it will only return
the dishes with priceRange = “$“.


**Here are my code:**

**Dinner.js component**:

    import SearchFilter from "SearchFilter.js"
    export default function Dinner() {
    
      const [foodName, setFoodName] = useState('')
      const [isVegetarian, setIsVegetarian] = useState('')
      const [priceRange, setPriceRange] = useState('$')
      const [foodList, setFoodList] = useState([])
    
      // Get data from the DB and display it:
      useEffect(() => {
        let unmounted = false
        Axios.get("https://my-app.com/read")
          .then((response) => {
            if (!unmounted) {
              setFoodList(response.data)
            }
          })
          .catch(error => {
            console.log(error)
            return
          })
        return () => {
          unmounted = true
        }
      }, [foodList])
    
      return ( 
        <div > {
          foodList.length > 0 && foodList.map((val, key) => {
              return (
                // Display a table of data here
                ...
              )
            }
          } 
        </div>
       )
    }

SearchFilter.js component:

export default function SearchFilter(props) {
  const [searchedFood, setSearchedFood] = useState([])
  const [textSearch, setTextSearch] = useState('')
  const [priceDropdown, setPriceDropdown] = useState('')
  const [vegDropdown, setVegDropdown] = useState('')

 // The problem is in here:
  const newSearch = props.foodList.filter((value) => {
        return (
          value.foodName.toLowerCase().includes(textSearch.toLowerCase()) &&
          value.priceRange.toLowerCase().includes(priceDropdown.toLocaleLowerCase()) 
          && value.isVegetarian.includes(vegDropdown.toLowerCase())
        )
      }
  )

  const handleSearch = (event) => {
    event.preventDefault()
    if (textSearch !== '') {
      setSearchedFood(newSearch)
    }
  }

  const clearSearch = (event) => {
    event.preventDefault()
    setSearchedFood([])
    setTextSearch('')
    setPriceDropdown('')
    setVegDropdown('')
  }


  return (
    <section className="search">
      <form className="search__form">
        <div className="search__controls">
          <label htmlFor="text-search">Search a dish: </label>
          <input type="text" placeholder="Search food name" name="text-search" autoComplete="off" value={textSearch} onChange={(event) => {setTextSearch(event.target.value)
            console.log(event.target.value)
          }} />
        </div>
        <div className="search__controls">
          <label>Filter by price range: </label>
          <select value={priceDropdown} onChange={(event) => {setPriceDropdown(event.target.value)}} >
            <option value="">All</option>
            <option value="$">$</option>
            <option value="$$">$$</option>
            <option value="$$$">$$$</option>
          </select>
        </div>
        <div className="search__controls">
          <label htmlFor="veg-dropdown">Filter by vegetarian: </label>
          <select name="veg-dropdown" value={vegDropdown} onChange={(event) => {setVegDropdown(event.target.value)}} >
            <option value="">--</option>
            <option value="No">No</option>
            <option value="Yes">Yes</option>
          </select>
        </div>
        <button className="btn" onClick={handleSearch}><HiSearch /></button>
        <button className="btn" onClick={clearSearch}><MdClear /></button>
      </form>
      <div className="data-result">
        {searchedFood.map((value, key) => {
          return (
            <div key={key}>
              {value.isVegetarian === "yes" 
                ? <p>{value.foodName}{<FaSeedling className="i-veggie" />}</p>
                : <p>{value.foodName}</p>
              }
              <p>{value.priceRange}</p>
            </div>
          )
        })}
      </div>
    </section>
  );
}

‘ More Details ‘ button pushes aligned div content out of alignment

I have two rows of four div class thumbnails with a see more details button, which when pressed shows more text. When I was testing a single thumbnail it worked fine, but now with two rows of thumbnails. When the button is clicked, the other thumbnails are pushed out of the singly. I have tried to aligned these with inline block but this change made the ‘see more’ text hidden underneath the thumbnail as the next row doesn’t drop the content down.

On another page I have a <h2 in-between the thumbnail rows and this works perfectly but when the two rows are directly after each other they don’t react how it should. Either showing the text under the thumbnail or displacing the whole next row of thumbnails.

function toggle(button) {

  const moreDetailses = document.querySelectorAll(".moreDetails");
  for (let i = 0; i < moreDetailses.length; i++) {
    moreDetailses[i].style.display = "none";
  }
}
.thumbnail-row {
  height: 400px;
  width: auto;
}

.thumbnail-frame {
  width: 19.75%;
  height: auto;
  margin-left: 4%;
  float: left;
}

.thumbnail-frame a {
  margin: 0;
}

.thumbnail-frame h3 {
  text-align: center;
}

.thumbnail-frame h4 {
  text-align: center;
}

.thumbnail {
  background-color: black;
  width: 100%;
  height: 350px;
  display: inline-block;
  /* makes it fit in like an <img> */
  background-size: cover;
  /* or contain */
  background-position: center center;
  background-repeat: no-repeat;
}
<div class="thumbnail-row">
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 01 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 02 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 03 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 04 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
</div>

<div class="thumbnail-row">
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 05 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
  <div class="thumbnail-frame">
    <div class="thumbnail" style="background-image: url(myharddrivedirctory);"></div>
    <div class="details">
      <div class="moreDetails">
        <h3> episode 06 details </h3>
      </div>
      <button title="Click to Show" type="button" onclick="toggle(this)">More Details</button>
    </div>
  </div>
</div>

JavaScript data attributes and dataset confusion

I am learning JavaScript and I saw a video about creating tabs using HTML, CSS, and JavaScript. But I am not understanding how the code is working. This is a codepen of the code: Tabs Codepen by WebDevSimplified. To be more specific I am not understanding what the value of target will be in this line const target = document.querySelector(tab.dataset.tabTarget);. Is it taking the values #home, #pricing and #about from data-tab-target and applying the class active on the specific data-tab-content based on which data-tab-target the user clicks on?