GeoJSON not showing

My issue is that i have the GeoJSON as a seperate Javascript file
It works fine

This is my code
`

<script>
    
    var map = L.map('map').setView([52.21, 5.96944], 3);

    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    }).addTo(map);

    var ned = L.geoJSON(geoJSONFeature).addTo(map);
</script>`

I tried watching youtube videos about it but it works for them when i do the same it doesnt

Scaling svg to fit circle

I’m making a vue.js app which uses tons of different icons, so I decided to make a small icons builder in node.js to standardize their use, and it also “crops” each svg so it fits its parent (using the viewbox attribute).

Though I stumbled upon an issue, scaling icons to fit a square makes more “squary” look larger than round ones, so I’d like to programatically scale them in a circle :

* {
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 2rem;
}

.title {
  font-family: sans-serif;
  font-weight: 600;
  font-size: 24px;
  margin: 0;
}

.grid {
  display: flex;
  gap: 1.5rem;
}

.group {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  text-align: center;
}

.bg {
  width: 80px;
  height: 80px;
  background-color: lightgray;
}

.zone {
  border: 2px solid red;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.zone--wanted {
    border-radius: 50%;
  }

.icon {
  width: 100%;
  height: 100%;
  background-color: coral;
}

.icon--rounded {
  border-radius: 20%;
}
  
.icon--circle {
  border-radius: 50%;
}
  
.icon-scaled--rounded {
  width: 80%;
  height: 80%;
}

.icon-scaled--square {
  width: 70.71068%;
  height: 70.71068%;
}
<div class="container">
  <p class="title">What I have :</p>
  <div class="grid">
    <div class="bg">
      <div class="zone">
        <div class="icon"></div>
      </div>
    </div>
    <div class="bg">
      <div class="zone">
        <div class="icon icon--rounded"></div>
      </div>
    </div>
    <div class="bg">
      <div class="zone">
        <div class="icon icon--circle"></div>
      </div>
    </div>
  </div>
  <p class="title">What I want :</p>
  <div class="grid">
    <div class="bg">
      <div class="zone zone--wanted">
        <div class="icon icon-scaled--square"></div>
      </div>
    </div>
    <div class="bg">
      <div class="zone zone--wanted">
        <div class="icon icon--rounded icon-scaled--rounded"></div>
      </div>
    </div>
    <div class="bg">
      <div class="zone zone--wanted">
        <div class="icon icon--circle"></div>
      </div>
    </div>
  </div>
</div>

Do you guys have an idea on how to do this ?

transfer invoice info from the entry sheet to the data sheet by apps script in google sheets

I wrote a code that transfer the info from the entry sheet to the data sheet,
the problem is the invoice in the entry sheet may contain 100 rows to transfer,
and when I try this way the program became slower when the user write more than 10 rows.

function Entry() {
  var SS=SpreadsheetApp.getActiveSpreadsheet();
  var EE=SS.getSheetByName("entry");
  var DataSheet=SS.getSheetByName("data");
  var Blankrow=DataSheet.getLastRow()+1;
  var Blankrow2=DataSheet.getLastRow()+2;
  var Blankrow3=DataSheet.getLastRow()+3;
  var Blankrow4=DataSheet.getLastRow()+4;
 
  var EE2=EE.getRange("D6").getValue();
  var EE3=EE.getRange("D7").getValue();
  var EE4=EE.getRange("D8").getValue();

  DataSheet.getRange(Blankrow,1).setValue(EE.getRange("D3").getValue());
  DataSheet.getRange(Blankrow,2).setValue(EE.getRange("F3").getValue());
  DataSheet.getRange(Blankrow,3).setValue(EE.getRange("D5").getValue());
  DataSheet.getRange(Blankrow,4).setValue(EE.getRange("E5").getValue());
  DataSheet.getRange(Blankrow,5).setValue(EE.getRange("G5").getValue());
  
  if(EE2!=""){
  DataSheet.getRange(Blankrow2,1).setValue(EE.getRange("D3").getValue());
  DataSheet.getRange(Blankrow2,2).setValue(EE.getRange("F3").getValue());
  DataSheet.getRange(Blankrow2,3).setValue(EE.getRange("D6").getValue());
  DataSheet.getRange(Blankrow2,4).setValue(EE.getRange("E6").getValue());
  DataSheet.getRange(Blankrow2,5).setValue(EE.getRange("G6").getValue());
  }
  if(EE3!=""){
  DataSheet.getRange(Blankrow3,1).setValue(EE.getRange("D3").getValue());
  DataSheet.getRange(Blankrow3,2).setValue(EE.getRange("F3").getValue());
  DataSheet.getRange(Blankrow3,3).setValue(EE.getRange("D7").getValue());
  DataSheet.getRange(Blankrow3,4).setValue(EE.getRange("E7").getValue());
  DataSheet.getRange(Blankrow3,5).setValue(EE.getRange("G7").getValue());
  }
if(EE4!=""){
  DataSheet.getRange(Blankrow4,1).setValue(EE.getRange("D3").getValue());
  DataSheet.getRange(Blankrow4,2).setValue(EE.getRange("F3").getValue());
  DataSheet.getRange(Blankrow4,3).setValue(EE.getRange("D8").getValue());
  DataSheet.getRange(Blankrow4,4).setValue(EE.getRange("E8").getValue());
  DataSheet.getRange(Blankrow4,5).setValue(EE.getRange("G8").getValue()); 
  }

  EE.getRange("D3").clearContent();
  EE.getRange("H3").clearContent();
  EE.getRange("J3").clearContent();
  EE.getRange("D5:D23").clearContent();
  EE.getRange("E5:E23").clearContent();
  EE.getRange("G5:G23").clearContent();
}

I want a way that make the code run faster.

Please I, want to replace ckeditor content when selected option has change but dosent work

jquery part: le jquery que j’ai ajouter et le contenu ne change pas alors que le ” alert(modele);” travaille bien

<script>
    $(document).ready(function() {
        $("select.modele").change(function() {
            var modele = $(this).children("option:selected").val();
            $("#model-body").html("<span>Un élément span</span>");
            alert(modele);
        });
    });
</script>

text editor: le ckeditor dans lequel devrait s’opérer la modification mais cela ne marche pas

<textarea name="contenu" id="classic-editor" class="form-control" row="10" required>
     <div class="f-22" id="model-body">
                                                                  
     </div>
</textarea>

C’est ce que j’ai essayé mais ça ne marche pas

Chrome – In the new tab “Save As…” disabled in right click menu when displaying generated HTML

In my frontend app I generate the HTML page as string and then open a new tab with JavaScript and write the html to the tab’s document, like so:

const newTab = window.open('about:blank', '', '');
newTab.document.write(this.fullRenderedHTML);

As a result the Save as option in the right click menu is disabled. Is there a way to make it possible for the user to save the page?

I expect the user to be able to save the generated HTML.
Here’s a codepen link to reproduce the issue.
https://codepen.io/socreative/pen/bGJxRLK

Click the Open Tab button then try saving the page in the new tab

Why is client.query not being called in my jest test?

mocking the apollo hook

jest.mock("@apollo/client", () => ({
  ...jest.requireActual("@apollo/client"),
  useApolloClient: () => ({
    query: jest.fn().mockResolvedValueOnce({
      data: { myReturnValue: { some: "data" } },
      loading: false,
      errors: undefined,
    }),
  }),
}))

my function

  const myFunction = (input) => {
    console.log("called this?") // this 100% gets called in the test
    const data = { ...defaultData, ...input }

    return client
      .query({
        query: Query,
        fetchPolicy: "network-only",
        variables: {},
      })
      .then(({ data, errors }) => {
        if (!data?) {
          alert(errors)
        } else {
          console.log("in else block") // this 100% gets called in the test
          runFunction()
        }
      })
  }

in my test it is logging: “in else block”

and in my test I have:

fireEvent.click(screen.getByText("My Button Text"))
await waitFor(() => expect(useApolloClient().query).toBeCalledTimes(1))

In the test output I get

Expected number of calls: 1
Received number of calls: 0

why is this? It definitely called client.query as it got in the logs

Offline/online event listeners stopped working

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    Testing: <span id="status">Not Detected! </span>
  </body>
  <script>
    window.addEventListener("offline", function (e) {
      alert("offline");
    });
    window.addEventListener("online", function (e) {
      alert("online");
    });

    // window.addEventListener("load", (event) => {
    //   setInterval(() => {
    //     const statusDisplay = document.getElementById("status");
    //     statusDisplay.textContent = navigator.onLine ? "Online" : "OFFline";
    //   }, 100);
    // });
  </script>
</html>

It is working in some computers but in my computer it is just working on Firefox browser and not on other browsers – chrome, Opera, Brave, Edge.
I am using
Distributor ID: Ubuntu
Description: Ubuntu 23.10
Release: 23.10

Chrome Version
Version 122.0.6261.94 (Official Build) (64-bit)
I also tested on the latest version but not working.

Not getting any error but when setting ‘offine’ from network tab it is working fine.
But turning aeroplane mode on not triggering the event.

I tried all other methods too available on the internet but did not get any solution.
I want the solution. I want to show alert or message on no internet connection.

how to display values sent from the backend to frontend

As shown in the code posted below, i have a web-service wsSentinelhubEngineProcessor, and i want to display what the backend sends, i want to display the following in the forntend:

res.send({
    processAPIResCode:processAPIResults.resultCode, 
    processAPIContents:processAPIResults.contents, 
    processAPIPathToTIFF:processAPIPathToTIFF.fullPath, 
});

for the code posted in frontend section, the following log message displays undefined while there is values sent from the backend:

this.#msg = ({msg:verboseTag + 'postUserInputSettings().successful communication with the web-service /wsSentinelhubEngineProcessor.', 
    procAPIResCode: procAPIResCode,
    procAPIContents: procAPIContents,
    procAPIPathToTIFF: procAPIPathToTIFF,
});
        

please let me know how to fix this issue

frontend:

this.#wsSentinelhubEngineProcessor = new WSSentinelhubEngineProcessor(this.#clsDigitizationPolygonInteractionsInst);
    this.#wsSentinelhubEngineProcessor.setRequestOptionsParams(this.#ndviCompContextObj);
    
    this.#wsSentinelhubEngineProcessor.fetchNDVIsTIFF((procAPIResCode, procAPIContents, procAPIPathToTIFF) => {
        this.#msg = ({msg:verboseTag + 'postUserInputSettings().successful communication with the web-service /wsSentinelhubEngineProcessor.', 
            procAPIResCode: procAPIResCode,
            procAPIContents: procAPIContents,
            procAPIPathToTIFF: procAPIPathToTIFF,
        });
        console.log(this.#msg); //this message displays undefined  <<<<<<<<<<==========================
    })
    .then(res => {
        this.#msg = ({msg:verboseTag , response:res});
        console.log(this.#msg);// this log displays the contents sent from the backend <<<<<<<<<<<<<<<<=============================
                    

webservice:

fetchNDVIsTIFF(onResult) {
    return new Promise(async (resolve, reject) => {
        const ws = endPointsURLs.VUE_NEWSWM_APP_LOCAL_HOST_3000.description + endPointsURLs.VUE_NEWSWM_APP_PATH.description + BackendWssConstants.CONST_WS_SENTINELHUB_ENGINE_NDVIS_TIFF.description;
        await fetch(ws, this.#requestOptions)
        .then(response => response.text())
        .then(response => {
            resolve(response);
            onResult(response.processAPIResCode, response.processAPIContents, response.processAPIPathToTIFF);
        })
    });
    

retruned values from the backend:

res.send({
    processAPIResCode:processAPIResults.resultCode, 
    processAPIContents:processAPIResults.contents, 
    processAPIPathToTIFF:processAPIPathToTIFF.fullPath, 
});

I want to add the automatically Dropdown Box based on the First value

This is the Image of Google Form. In this form I want to add the google apps script for automatically select the Question -2 Value (Item Name) based on Question-1 Value (SKU Code).
This is the image of data sheet. This is the image of sheet from I want the value in the google form.

I tried many thing but not get the desirable results. I tried i.e., Formulas, Functions, Codes etc to change the values but not getting which i want.

Problems with making javascript connecting with php and vice-versa [closed]

So, I have this file called home.php and this one called java.js and can’t make them work together.
Both should work just fine but they don’t, I have this usb stick to read nfc tags, the tag only does a code like 11111a11a1 and then it does enter automatically. The thing is, I want to use autofocus so that I don’t need to click in anything to use it on a tablet, but then the tag writes infinitely.
Everything with the database, removing image after 1 second of no input and autofocus should be working just fine.

To do:
-Basically, the objective is stop the tag from reading or the form from executing or something like that so if the tag is read 2 times in a row, it stops and only starts reading again when the tag changes (not working though).

I’ve tried a lot of things but the most effective until now is a temporary variable(Not temporary though) in the database with the id of 1 so I use it to know if the code inserted is equal to the temporary but it’s not working as intended.

You can change anything you want, I just need the part where it displays the image or video to stay and the form with the input and label (don’t worry about the css)

I thank and congratulate anyone that finds a good solution because it is damn hard for me 🙁
And yes, I know that using the database for storing a variable is kind of dumb but a genius ideia at the same time, so if you want to store a bunch of values without using a cookie or something like that, you can just send it and retrieve it later. xd

home.php

<?php
include "config.php";

try {
    // Check if the form is submitted
    if (isset($_POST['searchTerm'])) {
        // Fetch data from the form
        $filename = $_POST['searchTerm'];

        // Update the filename in the existing row of the media table
        $stmt = $conn->prepare("UPDATE media SET filename = :filename WHERE id = 1");
        $stmt->bindParam(':filename', $filename, PDO::PARAM_STR);
        $stmt->execute();

        // Find the row with the same filename as the one stored in id 1
        $stmt = $conn->prepare("SELECT * FROM media WHERE filename = :filename AND id != 1 LIMIT 1");
        $stmt->bindParam(':filename', $filename, PDO::PARAM_STR);
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        // You can do something with $row if needed
        /* DEBUGGING var_dump($row); */
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- ... Your other head content ... -->
    <script src="java.js"></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <form id="searchForm" method="post" action="">
        <!-- Use the "for" attribute to associate the label with the input -->
        <label for="searchTerm">Search:</label>
        <input type="text" id="searchTerm" name="searchTerm">
    </form>

    <!-- Display any media content based on the search term -->
    <?php
    // Display the image or video based on the initial search or when the form is submitted
    if (isset($_POST['searchTerm']) && $row !== false) {
        $fileType = $row['file_type'];
        
        if ($fileType === 'image') {
            echo "<img id='resultMedia' src='uploads/{$row['description']}.{$row['file_extension']}' class='' type='image/{$row['file_extension']}'>";
        } elseif ($fileType === 'video') {
            echo "<video id='resultMedia' width='640' height='360' controls autoplay loop>
                    <source src='uploads/{$row['description']}.{$row['file_extension']}' type='video/{$row['file_extension']}'>
                    Your browser does not support the video tag.
                  </video>";
        }
    } elseif (isset($_POST['searchTerm'])) {
        echo "No matching media found.";
    }
    ?>

</body>
</html>

java.js

document.addEventListener("DOMContentLoaded", function () {
    document.getElementById('searchTerm').focus();

    // Initialize the no input timer
    var noInputTimer = setTimeout(function () {
        // Hide the image or video if there is no input for more than 1 second
        var resultMedia = document.getElementById('resultMedia');
        resultMedia.src = '';
        resultMedia.style.display = 'none'; // Hide the video player
    }, 1000);

    // Variable to store the current NFC tag code
    let currentNfcTagCode = null;

    // Counter to track the number of consecutive readings of the same code
    let consecutiveReadings = 0;

    // Function to start reading process when NFC tag is detected
    function startReading() {
        // function to read NFC tag
        function readNfcTag() {
            //NFC tag code
            const NfcTagCode = document.getElementById('searchTerm').value;

            // Return simulated NFC tag code
            return NfcTagCode;
        }

        // Read NFC tag
        const tagCode = readNfcTag();

        // Check if the current tag code is the same as the previous one
        if (tagCode === currentNfcTagCode) {
            // Increment consecutive readings counter
            consecutiveReadings++;

            // Check if consecutive readings exceed a certain threshold
            if (consecutiveReadings >= 3) {
                // Stop reading the same code temporarily
                console.log("Same code read multiple times. Stopping reading temporarily.");
                return;
            }
        } else {
            // Reset consecutive readings counter if the code changes
            consecutiveReadings = 0;

            // Update current tag code
            currentNfcTagCode = tagCode;

            // Proceed with processing the new code
            console.log("New code read:", currentNfcTagCode);

            // Get the current value of the search input
            var searchTerm = currentNfcTagCode; // Use NFC tag code as search term

            // Create a new XMLHttpRequest object
            var xhr = new XMLHttpRequest();

            // Configure it to make a POST request to home.php
            xhr.open('POST', 'home.php', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

            // Define the callback function to handle the response
            xhr.onload = function () {
                if (xhr.status === 200) {
                    // Get the reference to the img tag
                    var resultImage = document.getElementById('resultMedia');

                    // Check if responseText is not empty
                    if (xhr.responseText.trim() !== "") {
                        // Set the src attribute of the img tag with the response from the server
                        resultImage.src = 'uploads/' + xhr.responseText + '.jpg';
                    }

                    // Save the current timestamp to localStorage
                    localStorage.setItem('lastFocusTimestamp', Date.now());

                    // Clear the search input after 2 seconds
                    setTimeout(function () {
                        document.getElementById('searchTerm').value = '';

                        // Automatically focus on the search input
                        document.getElementById('searchTerm').focus();
                    }, 3000);
                }
            };

            // Send the AJAX request with the search term
            xhr.send('searchTerm=' + encodeURIComponent(searchTerm));

            // Reset the no input timer
            clearTimeout(noInputTimer);
            noInputTimer = setTimeout(function () {
                // Hide the image if there is no input for more than 1 second
                var resultImage = document.getElementById('resultMedia');
                resultImage.src = '';
            }, 1000);
        }

        // Introduce a delay before attempting to read again
        setTimeout(startReading, 2000); // Repeat every 2 seconds
    }

    // Check if there is a timestamp in localStorage
    var lastFocusTimestamp = localStorage.getItem('lastFocusTimestamp');

    // Check if the page was reloaded in the last 5 seconds
    if (lastFocusTimestamp && Date.now() - parseInt(lastFocusTimestamp, 10) < 5000) {
        // Automatically focus on the search input
        document.getElementById('searchTerm').focus();
    }
});

I’m reading a large image file from local file system in chunks using Filereader API. I need a solution to render the image as the chunks are received

Rendering large image using buffer in chunks

I used FileReader API to read large files in chunks. I used this code

chunkReaderBlock(0, 65536, file);

function chunkReaderBlock(_offset, length, file) {
var r = new FileReader();

var blob_file.slice(_offset, length _offset);

r.onload readEventHandler;

r.readAsDataURL(blob);
}

Now I need a solution to render the image buffer received progressively as a chunks without waiting for the whole file to be read

Why the Component always re-render why it doesn’t change anything?

I got some trouble with the MainPage component, because the BestSellers component always re-renders whenever the ProductList re-renders. I use 2 different states and actions for them.

Here my MainPage:

const LargeProductCard = ({ product }) => {
  let truncatedTitle =
    product.name.length > 26
      ? `${product.name.substring(0, 23)}...`
      : product.name;
  const navigation = useNavigation();

  return (
    <TouchableOpacity
      style={styles.largeCard}
      onPress={() => navigation.navigate('Product', { id: product._id })}
    >
      <Text style={styles.productName}>{truncatedTitle}</Text>
      <Image
        source={{ uri: product.images[0].url }}
        style={styles.productImage}
      />
      <Text style={styles.buyNow}>BUY NOW!</Text>
    </TouchableOpacity>
  );
};

const BestSellers = () => {
  const dispatch = useDispatch();
  const [currentBestSellerIndex, setCurrentBestSellerIndex] = useState(0);
  const { bestSellers, error, loading } = useSelector(
    (state) => state.bestSellers
  );

  useEffect(() => {
    if (error) {
      ToastAndroid.show(error.message, ToastAndroid.LONG)
    }

    const fetch = async () => {
      if (bestSellers) return;

      await dispatch(getBestSellers());
    };
    fetch();
  }, [bestSellers]);

  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentBestSellerIndex((prevIndex) => (prevIndex + 1) % 5);
    }, 5000);

    return () => clearInterval(interval);
  });

  if (loading || bestSellers === undefined) {
    return <ActivityIndicator size="large"></ActivityIndicator>;
  }

  return (
    <View>
      {bestSellers && bestSellers.length > 0 && (
        <LargeProductCard product={bestSellers[currentBestSellerIndex]} />
      )}
    </View>
  );
};

const ProductList = () => {
  const dispatch = useDispatch();
  const [currentPage, setCurrentPage] = useState(1);
  const [loadingMore, setLoadingMore] = useState(false);
  const [showList, setShowList] = useState([]);

  const { products, error, productsFounded } = useSelector(
    (state) => state.products
  );

  useEffect(() => {
    if (error) {
      ToastAndroid.show(error.message, ToastAndroid.LONG);
      dispatch(clearErrors());
    }

    dispatch(getProducts('', 1, [0, 9999999], '', 0));
  }, []);

  useEffect(() => {
    if (productsFounded || productsFounded > 0) {
      const newProducts = products.filter(
        (product) => !showList.find((item) => item._id === product._id)
      );

      setShowList([...showList, ...newProducts]);
    }
  }, [products]);

  const fetchMoreProducts = async () => {
    if (loadingMore || currentPage >= Math.ceil(productsFounded / 4)) {
      return;
    }

    setLoadingMore(true);
    const nextPage = currentPage + 1;

    await dispatch(getProducts('', nextPage, [0, 9999999], '', 0));

    setCurrentPage(nextPage);
    setLoadingMore(false);
  };

  return (
    <FlatList
      data={showList}
      renderItem={({ item }) => <SmallProductCard product={item} />}
      keyExtractor={(item) => item._id}
      onEndReached={fetchMoreProducts}
      onEndReachedThreshold={0.1}
      ListFooterComponent={loadingMore ? <Text>Loading...</Text> : null}
      numColumns={2}
      contentContainerStyle={styles.flatListContentContainer}
    />
  );
};

const MainPage = () => {
  const bestSeller = useMemo(() => <BestSellers />, []);

  return (
    <View style={styles.content}>
      <Text style={styles.bestSeller}>Best Seller</Text>
      <BestSellers />

      <Text style={styles.Title}>Our Products</Text>
      <ProductList />
    </View>
  );
};

Reducers for them:

export const productReducer = (state = { products: [] }, action) => {
  switch (action.type) {
    case ADMIN_PRODUCTS_REQUEST:
    case ALL_PRODUCTS_REQUEST:
      return {
        loading: true,
        products: [],
      };

    case ALL_PRODUCTS_SUCCESS:
      return {
        loading: false,
        products: action.payload.products,
        totalProduct: action.payload.totalProduct,
        resPerPage: action.payload.resPerPage,
        productsFounded: action.payload.productsFounded,
        bestSellers: action.payload.bestSellers,
      };
    case ADMIN_PRODUCTS_SUCCESS:
      return {
        loading: false,
        products: action.payload,
      };
    case ADMIN_PRODUCTS_FAILED:
    case ALL_PRODUCTS_FAILED:
      return {
        loading: false,
        error: action.payload,
      };
    case CLEAR_ERRORS:
      return {
        ...state,
        error: null,
      };

    default:
      return state;
  }
};

export const bestSellersReducer = (state = { bestSellers: [] }, action) => {
  switch (action.type) {
    case BEST_SELLERS_REQUEST:
      return {
        loading: true,
      };
    case BEST_SELLERS_SUCCESS:
      return {
        loading: false,
        bestSellers: action.payload.bestSellers,
      };
    case BEST_SELLERS_FAILED:
      return {
        loading: false,
        error: action.payload,
      };
    case CLEAR_ERRORS:
      return {
        ...state,
        error: null,
      };

    default:
      return state;
  }
};

Actions:

export const getProducts =
  (keywords, currentPage = 1, price, category, ratings) =>
  async (dispatch) => {
    try {
      dispatch({
        type: ALL_PRODUCTS_REQUEST,
      });

      let link = `${apiURL}/products?keywords=${keywords}&page=${currentPage}&price[lte]=${price[1]}&price[gte]=${price[0]}&ratings[gte]=${ratings}`;

      if (category) {
        link = `${apiURL}/products?keywords=${keywords}&page=${currentPage}&price[lte]=${price[1]}&price[gte]=${price[0]}&category=${category}&ratings[gte]=${ratings}`;
      }

      const { data } = await axios.get(link);

      dispatch({
        type: ALL_PRODUCTS_SUCCESS,
        payload: data,
      });
    } catch (err) {
      dispatch({
        type: ALL_PRODUCTS_FAILED,
        payload: err.response.data.errMessage,
      });
    }
  };

export const getBestSellers = () => async (dispatch) => {
  try {
    dispatch({
      type: BEST_SELLERS_REQUEST,
    });

    const { data } = await axios.get(`${apiURL}/products/bestsellers`);

    dispatch({
      type: BEST_SELLERS_SUCCESS,
      payload: data,
    });
  } catch (err) {
    dispatch({
      type: BEST_SELLERS_FAILED,
      payload: err.response.data.errMessage,
    });
  }
};

Please help me to figure out why or give me some suggestions.

Thank for your guys supports.

I expect the component BestSellers does not re-render when the ProductList get update.

How to force a DOM refresh in a background tab for a Chrome extension?

I’m developing a Chrome extension that needs to parse DOM data from a background tab. However, I’ve noticed that the DOM data isn’t always up-to-date unless the user actively switches to that tab. I believe this behavior is part of Chrome’s optimization to save memory and improve performance. Is there any method or workaround that would allow me to force a refresh of the DOM in a background tab without requiring the user to switch to it? Any insights or suggestions would be greatly appreciated.

how to stick bottom of sidebars?

<div class="main-container">
 <div class="container">
   <div class="main__left_sidebar"><div class="main__wrap1">Левая боковая панель</div></div>
   <div class="main-content">Основной контент</div>
   <div class="main__right_sidebar"><div class="main__wrap3"> Правая боковая панель</div></div>
 </div>
</div>

While scrolling when it comes to end of sidebar i want to stick it. But when i use sidebarStick() it overflow footer because i used fixed. I am trying to use sticky. Howevere couldnt manage to do it

 if(scrollTop >= contentHeight - viewportHeight + sidebarTop) {
            sidebar_content.style.transform = `translateY(-${contentHeight - viewportHeight + sidebarTop + margin_bottom}px)`;
            sidebar_content.style.position = "fixed";
        }

How to stick when sidebar come to end so that it will not overlow footer? Full working example:

let left_sidebar = document.getElementsByClassName("main__left_sidebar")[0];
let right_sidebar = document.getElementsByClassName("main__right_sidebar")[0];

let left_sidebar_content = document.getElementsByClassName("main__wrap1")[0];
let right_sidebar_content = document.getElementsByClassName("main__wrap3")[0];


window.onscroll = () => {
  sidebarStick(left_sidebar, left_sidebar_content, 25);
  sidebarStick(right_sidebar, right_sidebar_content);

}

function sidebarStick(sidebar, sidebar_content, margin_bottom = 0) {
  let scrollTop = window.scrollY; // current scroll position
  let viewportHeight = window.innerHeight; //viewport height
  let contentHeight = sidebar_content.getBoundingClientRect().height; // current content height
  let sidebarTop = sidebar.getBoundingClientRect().top + window.scrollY; //distance from top to sidebar


  if (scrollTop >= contentHeight - viewportHeight + sidebarTop) {
    sidebar_content.style.transform = `translateY(-${contentHeight - viewportHeight + sidebarTop + margin_bottom}px)`;
    sidebar_content.style.position = "fixed";
  } else {
    sidebar_content.style.transform = "";
    sidebar_content.style.position = "";
  }
}
.main-container {
  margin: 0 auto;
  position: relative;
  padding: 0 30px;
  width: 100%;
  max-width: 1460px;
}

.container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-box-pack: justify;
  -ms-flex-pack: justify;
  justify-content: space-between;
  -webkit-box-align: start;
  -ms-flex-align: start;
  align-items: flex-start;
}

.main__left_sidebar,
.main__right_sidebar,
.main__wrap3,
.main__wrap1 {
  max-width: 290px;
  width: 100%;
}

.main-content {
  width: calc(100% - 628px);
}

.sidebar-right {
  max-width: 290px;
  width: 100%;
}

.box {
  color: white;
  width: 50px;
  background: red;
  height: 50px;
  margin: 10px 0;
}

footer {
  background: whitesmoke;
  text-align: center;
}
<div class="main-container">
  <div class="container">
    <div class="main__left_sidebar">
      <div class="main__wrap1">Левая боковая панель
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
        <div class="box">7</div>
      </div>
    </div>
    <div class="main-content">Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>Основной контент
      <br>
      <br>
    </div>
    <div class="main__right_sidebar">
      <div class="main__wrap3">Правая боковая панель
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
        <div class="box">7</div>
        <div class="box">8</div>
        <div class="box">9</div>
        <div class="box">10</div>
      </div>
    </div>
  </div>
</div>
<footer>
  Footer Footer Footer Footer Footer <br /> Footer Footer Footer Footer <br /> Footer Footer Footer Footer<br /> Footer Footer Footer Footer <br />
</footer>

Reload the page at intervals without scrolling [closed]

I use this Index.html to display metrics and update every 5 seconds.
The web page measurements.php updates every 5 seconds but does page scrolling and the page is back at the top.
How can I prevent scrolling when reloading?

I tried about 100-130 code snippets. The page always scrolls to the top.