Item Id not being passed to the async function in vue js

I have a vue file, where I have a checkbox for every row (corresponds to each object), which when clicked needs to toggle and hit the patch api. When clicked the checkbox, the item.id and checked=true needs to be passed in the async function. But when I check the console, the ItemId is undefined and also in network tab, the api has /undefined/ in the pk param.

The template is here..

<template>
  <div
    class="modal fade"
    id="manageLocationModal"
    tabindex="-1"
    aria-labelledby="manageLocationLabel"
    aria-hidden="true"
  >
    <div class="modal-dialog modal-dialog-centered modal-lg">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="manageLocationModalLabel">
            Locations List
          </h5>
          <button
            type="button"
            class="btn-close"
            data-bs-dismiss="modal"
            aria-label="Close"
          ></button>
        </div>
        <div class="modal-body px-4">
          <div class="collapse mb-4 border p-4" id="editLocation">
            <location-edit-form
              :item="item"
              @updated="itemUpdated"
              @cancel="cancelUpdate"
            ></location-edit-form>
          </div>

          <table class="table table-bordered">
            <thead>
              <tr>
                <th>S/N</th>
                <th>Local Name</th>
                <th>Latitude</th>
                <th>Longitude</th>
                <th>Variable</th>
                <th>Altitude</th>
                <th>Municipality</th>
                <th>Owners Name</th>
                <th>Operational</th>
                <th>Ward</th>
                <th>Started Date</th>
                <th>End Date</th>
                <th>Uploaded At</th>
                <th class="text-center">Actions</th>
                <th>Publish</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item, index) in location" :key="item.id">
                <th scope="row" v-if="meta.currentPage > 1">
                  <p v-if="index !== 9">
                    {{ meta.currentPage - 1 }}{{ ++index }}
                  </p>
                  <p v-else>
                    {{ ++index * meta.currentPage }}
                  </p>
                </th>
                <th v-else scope="row">
                  {{ ++index }}
                </th>
                <td>{{ item.Localname }}</td>
                <td>{{ item.latitude }}</td>
                <td>{{ item.longitude }}</td>
                <td v-if="item.variable.length">
                  {{ item.variable | filterVariableName }}
                </td>
                <td v-else>N/A</td>
                <td>{{ item.Altitude }}</td>
                <td>{{ item.Municipality }}</td>
                <td>{{ item.owners_name }}</td>
                <td>{{ item.Operational }}</td>
                <td>{{ item.Ward }}</td>
                <td>{{ item.Started_date }}</td>
                <td>{{ item.End_date }}</td>
                <td>{{ item.uploaded_at }}</td>
                <td class="text-center">
                  <button
                    class="btn btn-primary btn-sm me-3 mb-3"
                    @click.prevent="editLocation(item)"
                    :disabled="isUpdating"
                    data-bs-toggle="tooltip"
                    data-bs-placement="top"
                    title="Edit"
                  >
                    <i class="bi bi-pencil-square"></i>
                  </button>
                  <button
                    class="btn btn-danger btn-sm"
                    :disabled="isUpdating"
                    @click.prevent="deleteLocation(item.location_id)"
                    data-bs-toggle="tooltip"
                    data-bs-placement="top"
                    title="Delete"
                  >
                    <i class="bi bi-trash-fill"></i>
                  </button>
                </td>
                <td class="text-center">
                  <input
                    type="checkbox"
                    v-model="item.selectedItems"
                    :value="item.id"
                    @change="handleCheckboxChange(item.id, $event.target.checked)"
                    :checked="selectedItems.includes(item.id)"
                  />                  
                </td>
              </tr>
            </tbody>
          </table>

          <nav>
            <ul class="pagination" v-if="meta.totalPages > 1">
              <li
                class="page-item"
                v-if="meta.currentPage !== 1 && meta.totalPages > 1"
              >
                <button
                  class="page-link"
                  @click.prevent="getData(--meta.currentPage)"
                  :disabled="meta.currentPage === 1"
                >
                  Previous
                </button>
              </li>
              <li
                v-for="i in meta.totalPages"
                class="page-item"
                :class="{ active: meta.currentPage === i }"
                :key="i"
              >
                <a class="page-link" href="#" @click.prevent="getData(i)">{{
                  i
                }}</a>
              </li>
              <li
                class="page-item"
                v-if="
                  meta.currentPage !== meta.totalPages && meta.totalPages > 1
                "
              >
                <button
                  class="page-link"
                  @click.prevent="getData(++meta.currentPage)"
                  :disabled="meta.currentPage >= meta.totalPages"
                >
                  Next
                </button>
              </li>
            </ul>
          </nav>
        </div>
        <div class="modal-footer">
          <button
            type="button"
            class="btn btn-secondary"
            data-bs-dismiss="modal"
          >
            Close
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import LocationEditForm from "../../components/forms/LocationEditForm.vue";

export default {
  name: "ManageLocationModal",
  components: { LocationEditForm },
  data() {
    return {
      editCollapse: null,
      isUpdating: false,
      location: [],
      selectedItems: [], // Array to store selected item IDs
      meta: {
        totalItems: 0,
        totalPages: 0,
        currentPage: 1,
        pageSize: 10,
      },
      item: null,
    };
  },
  mounted() {
    this.getData();
  },
  filters: {
    filterVariableName(val) {
      const variable = val.map((el) => {
        return el.variable;
      });
      return variable;
    },
  },
  methods: {
    collapseEditForm(type) {
      if (!this.editCollapse) {
        this.editCollapse = new this.$bootstrap.Collapse(
          document.getElementById("editLocation")
        );
      }
      if (type === "show") {
        this.editCollapse.show();
      } else {
        this.editCollapse.hide();
      }
    },
    collapseEditLocationForm() {
      this.collapseEditForm("hide");
      this.item = null;
      this.isUpdating = false;
    },
    itemUpdated() {
      this.collapseEditLocationForm();
      this.getData();
      this.$emit("itemUpdated");
    },
    cancelUpdate() {
      this.collapseEditLocationForm();
    },
    async deleteLocation(id) {
      await this.$confirm({
        message: `Are you sure?`,
        button: {
          no: "No",
          yes: "Yes",
        },
        callback: (confirm) => {
          if (confirm) {
            this.$repository.location
              .delete(id)
              .then(() => {
                this.getData();
                this.$emit("itemUpdated");
                this.$toast.success("Location deleted");
              })
              .catch(() => {
                this.$toast.error("Deletion failed");
              });
          }
        },
      });
    },
    editLocation(item) {
      this.isUpdating = true;
      this.item = item;
      this.collapseEditForm("show");
    },
    async getData(page = 1) {
      this.meta.currentPage = page;

      let params = `?page_size=${this.meta.pageSize}&ordering=-uploaded_at`;

      if (this.meta.currentPage > 1) {
        params += `&page=${this.meta.currentPage}`;
      }

      await this.$repository.location.filter(params).then((res) => {
        this.location = res.data.results;
        this.meta.totalItems = res.data.count;
        this.meta.totalPages = Math.ceil(res.data.count / 10);
      });
    },
    async handleCheckboxChange(itemId, isChecked) {
      console.log("Checkbox changed:", { itemId, isChecked });
      if (!itemId) {
        console.error("Item ID is undefined");
        return;
      }
      this.isUpdating = true;
      try {
        if (isChecked) {
          console.log("Checkbox checked. Item ID:", itemId);

          // Check if the item is already in the selectedItems list
          if (!this.selectedItems.includes(itemId)) {
            this.selectedItems.push(itemId);
          }

          // Publish the item if checked
          await this.$repository.location.edit({ in_draft: false }, itemId);
          this.$toast.success("Location published successfully.");
        } else {
          console.log("Checkbox unchecked. Item ID:", itemId);

          // Remove the item from the selectedItems list
          if (this.selectedItems.includes(itemId)) {
            this.selectedItems = this.selectedItems.filter(
              (id) => id !== itemId
            );
          }
        }
      } catch (error) {
        this.$toast.error(
          `Error: ${error.response?.data?.error || error.message}`
        );
      } finally {
        this.isUpdating = false;
      }
    },
  },
};
</script>

<style scoped>
.modal-dialog {
  max-width: 85%;
  overflow: initial !important;
}
.modal-body {
  height: 80vh;
  overflow-y: auto;
}
.actions {
  min-width: max-content;
}
</style>

The code snippet of focus here is :

<input
                type="checkbox"
                v-model="item.selectedItems"
                :value="item.id"
                @change="handleCheckboxChange(item.id, $event.target.checked)"
                :checked="selectedItems.includes(item.id)"
              />

And the async function handleCheckboxChange is called.

The screenshot of console is here.

Screenshot of Console and api

Google Picker API giving Null user before completing authorization

I am using the google picker api example code from https://developers.google.com/drive/picker/guides/sample and when I tried authenticating with google, it always gives me back a null access token before I even complete the authorization part. Here is the following code I used for authorizing:

let tokenClient;
let accessToken = null;
let pickerInited = false;
let gisInited = false;


document.getElementById('authorize_button').style.visibility = 'hidden';
document.getElementById('signout_button').style.visibility = 'hidden';

/**
 * Callback after api.js is loaded.
 */
function gapiLoaded() {
  gapi.load('client:picker', initializePicker);
}
/**
 * Callback after the API client is loaded. Loads the
 * discovery doc to initialize the API.
 */
async function initializePicker() {
   
  await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');
  pickerInited = true;
  maybeEnableButtons();
}

/**
 * Callback after Google Identity Services are loaded.
 */
function gisLoaded() {
  tokenClient = google.accounts.oauth2.initTokenClient({
    client_id: CLIENT_ID,
    scope: SCOPES,
    callback: '', // defined later
  });
  gisInited = true;
  maybeEnableButtons();
}

/**
 * Enables user interaction after all libraries are loaded.
 */
function maybeEnableButtons() {
  if (pickerInited && gisInited) {
    document.getElementById('authorize_button').style.visibility = 'visible';
  }
}

/**
 *  Sign in the user upon button click.
 **/
function handleAuthClick() {
  tokenClient.callback = async (response) => {
    if (response.error !== undefined) {
      throw (response);
    }
    accessToken = response.access_token;
    document.getElementById('signout_button').style.visibility = 'visible';
    document.getElementById('authorize_button').innerText = 'Refresh';
    await createPicker();
  };

  if (accessToken === null) {
    // Prompt the user to select a Google Account and ask for consent to share their data
    // when establishing a new session.
    tokenClient.requestAccessToken({prompt: 'consent'});
  } else {
    // Skip display of account chooser and consent dialog for an existing session.
    tokenClient.requestAccessToken({prompt: ''});
  }
  console.log(tokenClient);
}

/**
 *  Sign out the user upon button click.
 */
function handleSignoutClick() {
  if (accessToken) {
    accessToken = null;
    google.accounts.oauth2.revoke(accessToken);
    document.getElementById('content').innerText = '';
    document.getElementById('authorize_button').innerText = 'Authorize';
    document.getElementById('signout_button').style.visibility = 'hidden';
  }
}

/**
 *  Create and render a Picker object for searching images.
 */
function createPicker() {
  console.log("Create Picker");
  const view = new google.picker.View(google.picker.ViewId.DOCS);
  view.setMimeTypes('image/png,image/jpeg,image/jpg');
  const picker = new google.picker.PickerBuilder()
      .enableFeature(google.picker.Feature.NAV_HIDDEN)
      .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
      .setDeveloperKey(API_KEY)
      .setAppId(APP_ID)
      .setOAuthToken(accessToken)
      .addView(view)
      .addView(new google.picker.DocsUploadView())
      .setCallback(pickerCallback)
      .build();
  picker.setVisible(true);
}

/**
 * Displays the file details of the user's selection.
 * @param {object} data - Containers the user selection from the picker
 */
async function pickerCallback(data) {
  if (data.action === google.picker.Action.PICKED) {
    let text = `Picker response: n${JSON.stringify(data, null, 2)}n`;
    const document = data[google.picker.Response.DOCUMENTS][0];
    const fileId = document[google.picker.Document.ID];
    console.log(fileId);
    const res = await gapi.client.drive.files.get({
      'fileId': fileId,
      'fields': '*',
    });
    text += `Drive API response for first document: n${JSON.stringify(res.result, null, 2)}n`;
    window.document.getElementById('content').innerText = text;
  }
}

From this, I get the popupp to log into my google account but the picker does not show up after I complete my login and when I added another button to forcefully build the picker, I get error 403 saying they dont have access to the page. It also seems that the await createPicker(); is never called

I tried moving around async tag in my function but nothing could stop the function from continuing and giving me a null user. I am hosting this on a Django server and I am trying to use OAuth2. I also tried tinkering with the redirect URI in the google console which is currently set to http://127.0.0.1:8000 as my authorized javascript origin and http://127.0.0.1:8000/callback as my authorized redirect URI. It seems the tokenClient.callback = async (response) => { is never running as well so any ideas why would be great! Any info/help is appreciated!

handle calling function exported from custom hook inside a useEffect reactjs

I have the following function which is used in multiple components to refresh a token:

// useRefresh is a custom hook
const refresh = useRefresh()

I have the following useEffect that should only really run on mount:

useEffect(() => {
    const handleRefresh = async () => {
        if (!tokenExpired || !isOpen) return
        const token = await refresh()
        tokenRef.current = token
    }

    const fetchStories = async () => {
        if (isOpen === false) return

        try {
            const result = await axiosPrivate.get(`${BASE_URL}/api/users/stories/${userId}`, {
                headers: { "x-auth-token": tokenRef.current },
            })
            dispatch(setUserStories({ userId, stories: result?.data?.stories }))
        } catch (err) {
            console.log(err)
            return
        }
    }

    const handleMount = async () => {
        await handleRefresh()
        await fetchStories()
        setIsLoading(false)
    }
    handleMount()
}, [isOpen, dispatch, axiosPrivate, userId, tokenExpired, refresh])

The problem I have is that this effect is ran in an infinite loop. this is due to the refresh function being recreated again and again.

I don’t want to wrap useCallback around the refresh function inside the custom hook as the refresh function is consumed in numerous components. I tried extracting the handleRefresh function outside the useEffect, and wrapped it inside a useCallback with empty dependency array, however I got a warning saying refresh is missing dependency to useCallback, and when I add it, the function is recreated on every render, defeating the purpose.
Any ideas on how to fix this issue? Thanks.

How do I check the validity of a HTML form element without triggering the invalid event

In my snippet below you can see that I have a form where I wish to only enable the submit button after all input fields are correctly filled out.

I do this by adding a change event listener to the form itself and then calling the checkValidity() function on the inputs inside the form. (in this example I have only 1) If all the checkValidity() checks return true, I enable the button, if not I disable it.

However, I noticed that calling checkValidity() this also triggers the invalid event listener when the input is invalid which is not desireable. I am using the invalid event listener for other stuff like if the form gets submitted anyways via keyboard shortcuts or other means so I can display an appropriate error message for the input fields because the submit call also will check the validity and trigger the invalid event.

So is there a way to check the validity of the input without triggering the invalid event so I can keep my invalid event listener and not have to write a custom validity check function for every single input?

const form = document.getElementById("form");
const input = document.getElementById("input");
const button = document.getElementById("button");
const checkbox = document.getElementById("checkbox");

form.addEventListener("change", () => {
    if (!checkbox.checked) return;
    if (input.checkValidity()) {
        button.removeAttribute("disabled");
    } else {
        button.setAttribute("disabled", "");
    }
})

input.addEventListener("invalid", (e) => {
    e.preventDefault();
    console.log("Invalid");
});

form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("submitted!");
});
button[disabled] {
    opacity: 0.5;
}
<form id="form">
  <input type="text" id="input" minLength="5">
  <button type="submit" id="button" disabled>Submit</button>
</form>
<br>
<label>
  <span>turn on change listener</span>
  <input type="checkbox" id="checkbox" checked>
</label>

creating a Blazor upload drag and drop button that links/binds to a ui table and displays the selected documents from selected popup?

enter image description here

what would the steps be to connect a a blazor drag and drop button to a ui table which displays selected documents onto the table? After selecting the document/multiple documents, whether it is pdf,png etc. It should display Name, LastName , Age , File Type and Date time uploaded

I created A class with Name, surname, Age, File Type and uploadedDateTime as well as a javascript file for dragging and dropping however when I select a file from the popup, the selected file has not showed up on the table

Ensuring Unique Code Usage in React Native and Expo Authentication

I’ve created a mobile app with react-native and expo for my studies. I’m trying to implement an authentication logic where the user has to enter an access code.

If the code complies with the verification rules, it will be stored in a mongodb database and allowed to log in to the app. It’s important to note that the code can only be used once.

I’ve tried all sorts of ways to do this logic, but without any success, I’m managing to use the code more than once, which I don’t want. Below is my backend and frontend code.

– server.js

require('dotenv').config();
const express = require('express');
const cors = require('cors'); // Importar cors
const { MongoClient } = require('mongodb');
const crypto = require('crypto');

const app = express();
const port = process.env.PORT || 3000;

app.use(cors()); // Usar cors
app.use(express.json());

const uri = process.env.MONGODB_URI;
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

let db;
client.connect()
  .then(() => {
    db = client.db('pesagem');
    console.log('Connected to MongoDB');
  })
  .catch(err => console.error('Error connecting to MongoDB', err));

const validateCode = (code) => {
  const codeParts = code.split('-');
  if (codeParts.length !== 4) {
    console.log('Invalid code format');
    return { valid: false, message: 'Código inválido.' };
  }

  const [timestamp, random, userType, hash] = codeParts;
  const originalData = `${timestamp}-${random}-${userType}`;
  const generatedHash = crypto.createHash('sha256').update(originalData).digest('hex');

  console.log('Generated Hash:', generatedHash);

  if (hash !== generatedHash) {
    console.log('Invalid code: hash does not match');
    return { valid: false, message: 'Código inválido.' };
  }

  let userTypeText;
  switch (userType) {
    case '0':
      userTypeText = '5';
      break;
    default:
      console.log('Invalid userType');
      return { valid: false, message: 'Código inválido.' };
  }

  return { valid: true, userTypeText };
};

app.post('/check-code', async (req, res) => {
  const { code } = req.body;

  if (!code) {
    console.log('Código não fornecido.');
    return res.status(400).send({ error: 'Código não fornecido' });
  }

  console.log('Received code:', code);

  const validationResult = validateCode(code);
  if (!validationResult.valid) {
    console.log('Validation result:', validationResult);
    return res.status(400).send({ error: validationResult.message });
  }

  try {
    const codesCollection = db.collection('usedCodes');
    const existingCode = await codesCollection.findOne({ code });

    if (existingCode) {
      console.log(`Código ${code} já utilizado.`);
      return res.status(400).send({ error: 'Este código já foi utilizado.' });
    }

    await codesCollection.insertOne({ code });
    console.log(`Código ${code} inserido com sucesso.`);
    return res.status(200).send({ message: 'Código válido e armazenado.', userType: validationResult.userTypeText });
  } catch (error) {
    console.error('Erro ao verificar o código', error);
    return res.status(500).send({ error: 'Erro interno do servidor' });
  }
});

app.listen(port, () => {
  console.log(`Servidor rodando na porta ${port}`);
});

– Login.js

const Login = ({ loginDone }) => {
  const [code, setCode] = useState('');
  const [isAlertVisible, setIsAlertVisible] = useState(false);
  const [alertMessage, setAlertMessage] = useState('');

  const showAlert = (message) => {
    setAlertMessage(message);
    setIsAlertVisible(true);
  };

  const closeAlert = () => {
    setIsAlertVisible(false);
  };

  const checkCode = async () => {
    console.log('checkCode function called');
    try {
      if (!code) {
        console.log('No code provided');
        showAlert('Por favor, insira um código para verificar.');
        return;
      }

      const codeParts = code.split('-');
      if (codeParts.length !== 4) {
        console.log('Invalid code format');
        showAlert('Código inválido.');
        return;
      }

      const [timestamp, random, userType, hash] = codeParts;
      const originalData = `${timestamp}-${random}-${userType}`;
      const generatedHash = await Crypto.digestStringAsync(
        Crypto.CryptoDigestAlgorithm.SHA256,
        originalData
      );

      console.log('Generated Hash:', generatedHash);

      if (hash !== generatedHash) {
        console.log('Invalid code: hash does not match');
        showAlert('Código inválido.');
        return;
      }

      console.log('Sending code to API:', code);
      const response = await axios.post(`${API_URL}/check-code`, { code });

      if (response.data.error) {
        console.log('API returned an error:', response.data.error);
        showAlert(response.data.error);
        loginDone(false, 0);
      } else {
        console.log('Login successful, user type:', response.data.userType);
        loginDone(true, response.data.userType);
        setCode('');
      }
    } catch (error) {
      if (error.response) {
        console.log('Erro na resposta da API:', error.response.data);
        showAlert('Erro ao verificar o código: ' + error.response.data.error);
      } else if (error.request) {
        console.log('Erro na requisição:', error.request);
        showAlert('Erro na conexão com o servidor.');
      } else {
        console.log('Erro desconhecido:', error.message);
        showAlert('Erro ao verificar o código.');
      }
      loginDone(false, 0);
    }
  };

When submitting form, I get “Cannot Post /”

I am building a reverse proxy, in it, there is a form box. It is supposed to get user input, and check if it is:

  1. a url;
  2. a url without the https:// header, which it adds;
  3. or plain text, which is routed into a search engine.

Wen submitting the form, no matter what is in it, it returns “Cannot Post /” in a blank page. My index.html form is this.

<div class="search-container">
    <p>Join the <a href="https://discord.gg/3TTahctF">discord</a>!</p>
    <form id="fs" method="POST">
        <input id="is" class="main-search" placeholder="A World, Uncensored" type="text" />
    </form>
</div>

In my index.js, which is connected, this.

window.addEventListener('load', () => {
  navigator.serviceWorker.register('../sw.js?v=4', {
    scope: '/a/',
  })
})

const form = document.getElementById('fs')
const input = document.getElementById('is')

if (form && input) {
  form.addEventListener("submit", async event => {
    event.preventDefault();
    processUrl(input.value, "");
  });
}

function processUrl(value, path) {
  let url = value.trim()
  const engine = localStorage.getItem('engine')
  const searchUrl = engine ? engine : 'https://www.google.com/search?q='

  if (!isUrl(url)) {
    url = searchUrl + url
  } else if (!(url.startsWith('https://') || url.startsWith('http://'))) {
    url = 'https://' + url
  }

  sessionStorage.setItem('GoUrl', __uv$config.encodeUrl(url))
  const dy = localStorage.getItem('dy')

  if (path) {
    location.href = path
  } else if (dy === 'true') {
    window.location.href = '/a/q/' + __uv$config.encodeUrl(url)
  } else {
    window.location.href = '/a/' + __uv$config.encodeUrl(url)
  }
}

function isUrl(val = '') {
  if (/^http(s?):///.test(val) || (val.includes('.') && val.substr(0, 1) !== ' ')) return true
  return false
}

First, I tried changing the form’s method, which gave me a similar error. Then, after doing research online, I came to this link. Although similar, it is focused on an express error, while mine is basic javascript (client side).

How to access OneSignal web push notifications data in order to perform other actions

I’m trying to access OneSignal web push notification data to update other parts of my website. However, the on(‘notificationDisplay’) or on(‘notificationDismiss’) events are not being triggered. My website is served over HTTPS, so that shouldn’t be the issue. Here’s my current implementation:

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151606" async=""></script>
  <script>
    var onesignalAppId = "1234567890";
    var idWriter = "12345";
    var OneSignal = window.OneSignal || [];

    if (onesignalAppId) {
      OneSignal.push(function() {
        OneSignal.init({
          appId: onesignalAppId,
          notifyButton: { enable: true },
          logLevel: 'trace'  // Enable verbose logging
        });

        OneSignal.showNativePrompt();

        OneSignal.on('notificationDisplay', function(event) {
          console.log('OneSignal notification displayed:', event);
          alert(event);
        });

        OneSignal.on('notificationDismiss', function(event) {
          console.log('OneSignal notification dismissed:', event);
        });

        OneSignal.on('subscriptionChange', function(isSubscribed) {
          console.log('Subscription changed:', isSubscribed);
        });

        if (idWriter) {
          OneSignal.setExternalUserId(idWriter);
        }
      });
    }
  </script>
</head>
<body>
  Content
</body>
</html>

I’ve seen similar questions suggesting that these events only work on HTTPS sites, but my site is indeed HTTPS. What could be the problem?

Are there any common issues or additional configurations that I might be missing? Any help would be appreciated.

React Context.Provider returns undefined

I have a Context.Provider with a value
When I import it in the child component with useContext it returns undefined
I don’t see what I’m missing here

For context here is the folder structure

src
    slider
        edit.js
        index.js
    slide
        edit.js
        index.js

build
    slider
        index.js
    slide
        index.js

index.js

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';

/**
 * Internal dependencies
 */
import Edit from './edit';
import save from './save';
import metadata from './block.json';

/**
 * Every block starts by registering a new block type definition.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
 */
registerBlockType( metadata.name, {
    /**
     * @see ./edit.js
     */
    edit: Edit,

    /**
     * @see ./save.js
     */
    save,
} );
import React, { createContext, useRef } from 'react'
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'

export const SlideContext = createContext()

export default function Edit() {
    const slideRefs = useRef([])

    const setSlideRef = (ref, index) => {
        slideRefs.current[index] = ref
        console.log('setSlideRef called with ref:', ref, 'and index:', index)
    }

    // some code omitted for brevity

    console.log('Rendering Slider component with context value:', { setSlideRef })

    const blockProps = useBlockProps()

    return (
        <SlideContext.Provider value={{ setSlideRef }}>
            <div {...blockProps}>
                <div className='splash-slider__wrapper'>
                    <div
                        className='splash-slider__track'
                    >
                        <InnerBlocks
                            allowedBlocks={['splash-blocks/slide']}
                            renderAppender={() => <InnerBlocks.ButtonBlockAppender />}
                            templateLock={false}
                        />
                    </div>
                </div>
            </div>
        </SlideContext.Provider>
    )
}

import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'
import { useEffect, useRef, useContext } from '@wordpress/element' // Same as React
import { SlideContext } from '../slider/edit' // Import the context from the parent block

export default function Edit({ attributes, setAttributes, clientId }) {
    const blockProps = useBlockProps({
        className: 'splash-slider__slide'
    })
    const slideRef = useRef()

    const slideContext = useContext(SlideContext)
    console.log('slideContext:', slideContext) // logs: undefined
    const { setSlideRef } = slideContext || {}

    useEffect(() => {
        console.log('slideRef.current:', slideRef.current) // logs correctly
        if (setSlideRef && slideRef.current) {
            console.log('Setting slideRef with clientId:', clientId)

            setSlideRef(slideRef, clientId)
        }
    }, [setSlideRef, clientId])

    return (
        <div {...blockProps} ref={slideRef}>
            // InspectorControls and PanelBody omitted for brevity
            <InnerBlocks />
        </div>
    )
}

Troubleshoot deploying cloud functions error with typecasting in node modules

I’m building a reactjs pwa. trying to implement cloud functions in my project.
I’m trying to deploy firebase cloud functions but getting the same error despite trying a couple of things:

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:13:11 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

13     data: AllowSharedBufferSource;
             ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:23:19 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

23     description?: AllowSharedBufferSource | undefined;
                     ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:56:14 - error TS2304: Cannot find name 'AvcBitstreamFormat'.

56     format?: AvcBitstreamFormat | undefined;
                ~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:60:11 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

60     data: AllowSharedBufferSource;
             ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:71:11 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

71     data: AllowSharedBufferSource;
             ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:74:11 - error TS2552: Cannot find name 'EncodedVideoChunkType'. Did you mean 'EncodedVideoChunk'?

74     type: EncodedVideoChunkType;
             ~~~~~~~~~~~~~~~~~~~~~

  ../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:266:13
    266 declare var EncodedVideoChunk: {
                    ~~~~~~~~~~~~~~~~~
    'EncodedVideoChunk' is declared here.

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:119:19 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

119     description?: AllowSharedBufferSource | undefined;
                      ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:137:13 - error TS2304: Cannot find name 'AlphaOption'.

137     alpha?: AlphaOption | undefined;
                ~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:140:19 - error TS2304: Cannot find name 'VideoEncoderBitrateMode'.

140     bitrateMode?: VideoEncoderBitrateMode | undefined;
                      ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:147:19 - error TS2304: Cannot find name 'LatencyMode'.

147     latencyMode?: LatencyMode | undefined;
                      ~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:173:13 - error TS2304: Cannot find name 'VideoPixelFormat'.

173     format: VideoPixelFormat;
                ~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:185:13 - error TS2304: Cannot find name 'AlphaOption'.

185     alpha?: AlphaOption | undefined;
                ~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:203:25 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

203     copyTo(destination: AllowSharedBufferSource, options: AudioDataCopyToOptions): void;
                            ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:214:21 - error TS2304: Cannot find name 'CodecState'.

214     readonly state: CodecState;
                        ~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:231:21 - error TS2304: Cannot find name 'CodecState'.

231     readonly state: CodecState;
                        ~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:250:25 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

250     copyTo(destination: AllowSharedBufferSource): void;
                            ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:262:20 - error TS2304: Cannot find name 'EncodedVideoChunkType'.

262     readonly type: EncodedVideoChunkType;
                       ~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:263:25 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

263     copyTo(destination: AllowSharedBufferSource): void;
                            ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:329:21 - error TS2304: Cannot find name 'CodecState'.

329     readonly state: CodecState;
                        ~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:346:21 - error TS2304: Cannot find name 'CodecState'.

346     readonly state: CodecState;
                        ~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:368:22 - error TS2304: Cannot find name 'VideoPixelFormat'.

368     readonly format: VideoPixelFormat | null;
                         ~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:374:25 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

374     copyTo(destination: AllowSharedBufferSource, options?: VideoFrameCopyToOptions): Promise<PlaneLayout[]>;
                            ~~~~~~~~~~~~~~~~~~~~~~~

../node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts:380:15 - error TS2304: Cannot find name 'AllowSharedBufferSource'.

380     new(data: AllowSharedBufferSource, init: VideoFrameBufferInit): VideoFrame;
                  ~~~~~~~~~~~~~~~~~~~~~~~


Found 23 errors in the same file, starting at: ../node_modules/@types/dom-webcodecs/webcodecs.genera

I have tried:

  • updating packages
  • reinstalling webcodec/ types/dom-webcodecs (getting up to date)
  • Googling around

Don’t know what else to try.

PixiJS character animated sprite not updating when getting reassigned

I am trying to update an animated sprite object and i have instantiated them like this: characterMovement["walk_down"] = PIXI.AnimatedSprite.fromFrames(animations["walk_down/walk_down"]); characterMovement["walk_up"] = PIXI.AnimatedSprite.fromFrames(animations["walk_up/walk_up"]); characterMovement["walk_left"] = PIXI.AnimatedSprite.fromFrames(animations["walk_left/walk_left"]); characterMovement["walk_right"] = PIXI.AnimatedSprite.fromFrames(animations["walk_right/walk_right"]);

I then assign it like this:
character = characterMovement["walk_down"];

then I have some code that dependign on what key is pressed the animated sprite object should change like this: if (keys['87'] && character.y > 0) { character= characterMovement["walk_up"];

however nothing happens when i reassign it.

I have tried just reassigning the textures like this: character.textures = characterMovement["walk_up"].textures; and that works but doesnt cycle through the animations.

Peeking the contents of NextRequest.body in Next.js middleware

This is my middleware.js file for Next.js:

import { NextResponse }         from 'next/server';
import { createCsrfMiddleware } from '@edge-csrf/nextjs';

const csrfMiddleware = createCsrfMiddleware({
    secret  : process.env.CSRF_SECRET,
    cookie  : {
        secure   : process.env.NODE_ENV === 'production',
        sameSite : 'strict',
        httpOnly : true
    }
});

export const middleware = async (req) => {
    const path = req.nextUrl.pathname;
    if (req.method === 'POST' && path === '/api/whatever') {
        try {
            console.warn(`checking skip in ${path}...`);
            const decoder = new TextDecoder('utf-8');
            let wholeBody = decoder.decode(await req.arrayBuffer());
            const json = JSON.parse(wholeBody);
            if (json.action === 'skip') {
                console.warn(`skipped: '${wholeBody}'`);
                return NextResponse.next();
            }
            else {
                console.warn('skip ignored');
                return csrfMiddleware(req); // body is unusable
            }
        }
        catch (err) {
            console.warn(`skip check failed in ${path}: ${err.message}`);
            return new NextResponse('Internal Server Error', { status: 500 });
        }
    }
    return csrfMiddleware(req);
};

Notice two things:

  1. I am using @edge-csrf/nextjs to prevent CSRF, but that’s not important.
  2. I am trying to skip the CSRF middleware by inspecting the CONTENTS of the payload.
    Yes. I know this is a weird case, and usually it’s done by ignoring a whole API path. But I want to know if it’s possible to do it this way.

Having said that, there is an issue right there in the line with the comment.
Before reaching that part, the body has been ‘consumed’ by (I guess) req.arrayBuffer().
Hence it cannot be used again.

So I wonder if is it possible to read the body and rewind the thing (haha) or peeking into it in some way.

Thanks for your ideas/comments.

Cloudflare Pages & apiKeys

Heya I am encountering an issue trying to get the request for my static website that was deployed to Cloudflare Workers to function and giving me errors my script. The error in the console on the page is VM1507:1 Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

My file structure is:

-functions
--env.js
-Images
-Scripts
--gallery.js
-Styles
-index.html

The primary focus is env.js and gallery.js.

env.js:

async function onRequest(context) {
  const folderID = context.env.folderID;
  const apiKey = context.env.apiKey;

  const response = new Response(JSON.stringify({ folderID, apiKey }));
  response.headers.set("Content-Type", "application/json");

  return response;
}

gallery.js:

async function fetchImages() {
  try {
    const envResponse = await fetch("/functions/env");
    const { folderID, apiKey } = await envResponse.json();

    const imageDataResponse = await fetch(
      `https://www.googleapis.com/drive/v3/files?q=${folderID}+in+parents&key=${apiKey}&fields=files(id,name,mimeType,thumbnailLink,webContentLink)`
    );
    const imageData = await imageDataResponse.json();
    displayImages(imageData.files);
  } catch (error) {
    console.error("Error fetching env data:", error);
  }
}

function displayImages(files) {
  const gallery = document.getElementById("gallery");
  const slidesContainer = document.createElement("div");
  slidesContainer.id = "slides";
  gallery.appendChild(slidesContainer);

  files.forEach((file, index) => {
    if (file.mimeType.startsWith("image/")) {
      const img = document.createElement("img");
      img.src =
        file.thumbnailLink ||
        `https://drive.google.com/uc?export=view&id=${file.id}`;
      img.alt = file.name;
      img.classList.add("slide");
      if (index === 0) {
        img.classList.add("active");
      }
      slidesContainer.appendChild(img);
    }
  });
  addGalleryNavigation();
}

function addGalleryNavigation() {
  const slides = document.querySelectorAll(".slide");
  let currentIndex = 0;

  document.getElementById("nextBtn").addEventListener("click", () => {
    slides[currentIndex].classList.remove("active");
    currentIndex = (currentIndex + 1) % slides.length;
    slides[currentIndex].classList.add("active");
  });

  document.getElementById("prevBtn").addEventListener("click", () => {
    slides[currentIndex].classList.remove("active");
    currentIndex = (currentIndex - 1 + slides.length) % slides.length;
    slides[currentIndex].classList.add("active");
  });
}

fetchImages();

I have tried putting a try catch for error handling and still getting the same error, I have also substituted the envData by hard coding in my apiKey and folderId variables back.

Is there a way to copy/get responses directly from chrome browser with python?

I have a python code that uses selenium, I’m not expert with web development and I’m trying to get responses from some dropdowns that are cascading each other, when you select a value from one dropdown it retrieves a response with the values of the next dropdown. One of those is a date picker that contains available days in JSON format instead of going through the calendar, I can know which one is available by getting this JSON response, I found a feature in Google Chrome that allows you to get this information if you open the developer tools and go to the Network tab -> right-click to the file -> copy -> copy response, is there any way to do the same or use this feature with code using python and selenium or maybe pure JavaScript? Selenium allows you to run JavaScript commands

Please see what I’m trying to explain in the below picture with Google:

enter image description here

I have found some suggested solutions in this post:

Selenium – python. how to capture network traffic’s response

But not sure if there’s any other straight-forward solution as I mentioned directly from browser.