Javascript: Determining the number of consecutive days (streak) in an array

I am trying to write a function that gets an array of dates (potentially unsorted, date_array) as input and determines the number of consecutive days that are in the array from a certain date (start_date) backwards, not including the start date.

Example:
start_date = 23.01.2023

date_array = [
01.01.2023,
02.01.2023,
20.01.2023, <- day 3 of the streak
21.01.2023, <- day 2 of the streak
22.01.2023, <- day 1 of the streak
22.01.2023, <- day 1 of the streak
23.01.2023,
24.01.2023]

Result:
streak_lenght: 3 days

The function I implemented is supposed to create a date range from the start date backwards and count, how many dates in the array are within the range. Every loop, the end date of the range goes one day further into the past. The loop continues as long as the number of dates within the range grow.

start date … start date – 1 day
start date … start date – days

However, for some reason the start date gets overwritten by the end date before the while loop starts…

I would greatly appreciate any help – or suggestions for better solutions to the problem. Thanks in advance!

const dateArray = [
  new Date("2022-12-31"), 
  new Date("2023-01-02"), // day 3 of streak
  new Date("2023-01-03"), // day 2 of streak 
  new Date("2023-01-03"), // day 2 of streak
  new Date("2023-01-04"), // day 1 of streak
  new Date("2023-01-05")];

const d_start = new Date("2023-01-05");

function currentStreak(dateArray, d_start) {
    // dateArray: Array of dates on which event was executed
    // d_start: start date of the streak, not included

    // Create a range d_start ... d_end, d_end starts one day before d_start

    let d_end = d_start
    d_end.setDate(d_start.getDate() - 1)
    let countPrev = -1
    let count = 0
    let streakCount = 0

    // Count how many array elements are in the range and continue loop while this number increases    
    while (count > countPrev) {
        countPrev = count
        // count number of array elements between start and end date
        count = dateArray.reduce((accumulator, currentValue) => {
          if((d_start > currentValue) && (currentValue > d_end))
          {
            accumulator += 1
          }
         return accumulator
        }, 0)
        // set new end date for next iteration
        d_end = d_end.setDate(d_end.getDate() - 1)
        streakCount = streakCount+1
    }
    return count;
  }

currentStreak(dateArray, d_start)

Locize saveMissing function failing with 400 request

Using a free trail account I am receiving 400 error on saving missing translation.

POST https://api.locize.app/missing/-apiKey-/latest/en/translation 400

Where -apiKey- is the api key provide on account creation.

Is this due to being on free account and just assume it works after purchase?
The preflight before this request is successful just not the actual POST.

Using i18n and this config:

i18n.use(Backend).use(LanguageDetector).use(initReactI18next).init({
  debug: true,
    fallbackLng: "en",
    saveMissing: true,
    backend: locizeOptions,
  });

Then within code for example:

{t("button.new", "New")}

passing the object prop as context to the function through binding

I’m trying to pass a prop as a context through binding Object prop to function ‘product’, however, in any way I got: this.product = undefined.
How could I fix this?

const product = function () {
  console.log("this.product?", this.product);
  console.log('arguments -->', arguments);
    return [].reduce.call(arguments, function(res, elem) {
      return res * elem;
    }, this.product);
};

// used this constant to store object this
const contextObj = {
  x: 10,
  argFromObj: function () {
    return this.x;
  },
};

const getProduct = product.bind(contextObj.argFromObj(), 2, 3);
console.log(getProduct(4, 5)); // 1200

Pushing object into Array of Arrays retains pointer to original object [duplicate]

I was wondering if anyone could help provide context on this one.

With the below example:

const finalArray: any[][] = []
const accumulatedArray: any[] = []

const ids = ['1','2']
for (const id of ids) {
    accumulatedArray.push({
        id: id,
    })
}

finalArray.push(accumulatedArray)

accumulatedArray.length = 0 // remove elements from array

console.log(finalArray) 

The above code will output [ [] ], which took me by surprise, I was expecting to see [ [ { id: '1' }, { id: '2' } ] ] but I can achieve this by creating a new array using a spread operator:

finalArray.push([...accumulatedArray])

question is
Why does the element in the array of arrays (finalArray) point to the accumulatedArray ?

Javascript Fetch not sending JWT httponly cookie to .Net Core 6 API

I’ve been working on implementing JWT and refresh_tokens. The latest attempt uses refresh_tokens stored in an httpOnly cookie. My API is a .Net Core 6 API, and using Swagger and Postman, things seem to work fine. I see the refresh_token cookie in the browser devtools Application Tab. In Swagger and Postman, when I run my refresh_token endpoint, which uses the httpContextAccessor to get the Request.Cookies, it’s fine. I see in the Request Headers, a cookie with my refresh_token.
Now, my attempts to replicate this work in VSCode running a live server is where I’m running into trouble. I’m using a vanilla JS front end and Fetch. My login code works fine:

fetch(loginUrl, {
   method: "POST",
   credentials: "include",
   body: JSON.stringify(authBody),
   headers: {
      "Content-Type": "application/json; charset=utf-8"
});

The Browser dev tools shows my cookie is fine.
My attempts to call my refresh_token endpoint however does NOT send the cookie.
I don’t see a cookie in the Request Headers. I’ve been trying some variations of the above fetch code but the cookie won’t go.
Now the only thing I can think of is a cors issue…
My API is running from VS2022 and is at https://localhost:7121 and my VSCode Live Server is http://localhost:5500.

On the API side, I’ve tried setting the cookie with:

HttpOnly = true,
Secure = true,
Expires = expireTime,

I’ve tried including some variations of SameSite too, but not much luck.
Any suggestions or help is greatly appreciated!

Drawing canvas is offset [webdev]

It’s very hard to explain. But I’ll try, the whole canvas is offset. I’m not sure how this even happened or how to fix it. It’s like when your mouse is in the top left corner of the page, and you started in the center, it matches up with the top left corner of the canvas element itself. Use the code snippets to see what I’m talking about.

JS:

let currentColor = null;

let inputs = document.getElementsByClassName("style2");

for (const input of inputs) {
  input.addEventListener("click", (e) => {
    if (e.detail !== 2) e.preventDefault();
  });
}


let arr = [];

for (let i = 0; i < inputs.length + 1; i++) {
  arr.push(i.toString());
}
arr.shift();

for (const input of inputs) {
  input.addEventListener("input", (e) => {
    const { value } = document.getElementById(e.target.id);
    currentColor = value;
    $("#selectedColor").css("background-color", value);
  })
    input.addEventListener("click", (e) => {
    const { value }  = document.getElementById(e.target.id);
    currentColor = value;
    $("#selectedColor").css("background-color", value);
  })
}

var rangeslider = document.getElementById("sliderRange");
const setSize = document.getElementById("setSize")
const submit = document.getElementById("submit")

submit.addEventListener("click", (e) => {
  rangeslider.value = setSize.value 
})

const button = document.getElementById("clear")
// create canvas element and append it to document body
var canvas = document.getElementById('canvas');
// some hotfixes... ( ≖_≖)
// get canvas 2D context and set him correct size
var ctx = canvas.getContext('2d');
resize();

// last known position
var pos = { x: 0, y: 0 };

window.addEventListener('resize', resize);
button.addEventListener('click', clear)
document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
document.addEventListener('mousemove', setPosition);


// new position from mouse event
function setPosition(e) {
  let canvas = document.getElementById("canvas")
  pos.x = e.clientX
  pos.y = e.clientY
}

// resize canvas
function resize() {
  ctx.canvas.width = 650;
  ctx.canvas.height = 375;
}

function draw(e) {
  // mouse left button must be pressed
  if (e.buttons !== 1) return;
  let canvas = document.getElementById('canvas');

  console.log(pos)
  ctx.beginPath(); // begin

  ctx.lineWidth = rangeslider.value;
  ctx.lineCap = 'round';
  ctx.strokeStyle = currentColor;

  ctx.moveTo(pos.x, pos.y); // from
  setPosition(e);
  ctx.lineTo(pos.x, pos.y); // to

  ctx.stroke(); // draw it!
}

function clear() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}



HTML:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>replit</title>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>

<body>

  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <div class="box5">
    <canvas class="canvas" id="canvas"></canvas>
  </div>
  
  <div class="box1">
    <button id="clear">Clear</button><br>
  </div>

  <div class="box1">
    <div class="rangeslider">
          <input type="range" min="1" max="100" value="5" class="myslider" id="sliderRange">
    </div>
  </div>
  <div class=box1>
    <div>
      <input id="setSize" type="text" placeholder="Set Brush Size... (Max 100)">
      <br>
      <button type="submit" id="submit" for="setSize">Submit</button>
    </div>
  </div>
  
  <div class="box">
      <div class="container">
        <input type="color" value="#000000" class="style2" id="1" />
      </div>
      <div class="container">
        <input type="color" value="#ffffff" class="style2" id="2" />
      </div>
      <div class="container">
        <input type="color" value="#ffffff" class="style2" id="3" />
      </div>
      <div class="container">
        <input type="color" value="#ffffff" class="style2" id="4" />
      </div>
      <div class="container">
        <input type="color" value="#ffffff" class="style2" id="5" />
      </div>
  </div>

  <div class="box">
    <label for="selectedColor">Current Color:
    <div id="selectedColor"></div>
  </div>

  
  <script src="script.js"></script>
</body>

</html>

CSS:

html, body {
  height: 100%;
  width: 100%;
  font-family: sans-serif;
  background-color: #B3B7B5;
/*   overflow: hidden; */
}

.style2 {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-color: transparent;
  width: 35px;
  height: 35px;
  border: none;
  cursor: pointer;
}


.style2::-webkit-color-swatch {
  border-radius: 50%;
  border: 3px solid #000000;
}
.style2::-moz-color-swatch {
  border-radius: 50%;
  border: 3px solid #000000;
}

.box {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 5px;
  max-width: 320px;
  margin: 0 auto;
  padding: 7.5px 10px;
}

.box1 {
    display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 5px;
  max-width: 9999px;
  margin: 0 auto;
  padding: 10px 10px;
}

.box5 {
    display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 5px;
  max-width: 650px;
  margin: 0 auto;
  padding: 10px 10px;
}

.box2 {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 5px;
  max-width: 9999px;
  margin: 0 auto;
  padding: 10px 10px;
}

#selectedColor {
  width: 100px;
  height: 30px;
  border: 3px solid black;
  border-radius: 5px;
  background-color: black;
}

.canvas {
  height: 350px;
  width: 650px;
  border: 3px solid black;
  border-radius: 5px;
  background-color: white;
  cursor: crosshair;
  position: relative;
/*   left: 50%; */
}

#clear {
  width: 50px;
  height: 35px;
  font-size: 15px;
  border-radius: 5px;
}

#submit {
  width: 59px;
  height: 23px;
  margin: auto;
  left: 35%;
  border-radius: 5px;
  position: relative;
}

.rangeslider {
    width: 50%;
}
  
.myslider {
    -webkit-appearance: none;
    background: #FCF3CF  ;
    width: 50%;
    height: 20px;
    opacity: 2;
   }
  
  
.myslider::-webkit-slider-thumb {
    -webkit-appearance: none;
    cursor: pointer;
    background: #34495E  ;
    width: 5%;
    height: 20px;
}
  
  
.myslider:hover {
    opacity: 1;
}

.rangeslider {
  left: 38%;
  position: absolute;
}

I know this code is kind of weird but please bare with me.

Send file attachments in next.js via nodemailer

I am trying to send file attachments in my Next.js app using nodemailer.

My current setup consists of:
ApplicationForm.tsx

import { sendEmailForm } from '../../../../lib/api';

const initialState: IApplicationFormData = {
  files: [],
};

const ApplicationForm = () => {
  const [formData, setFormData] = useState<IApplicationFormData>(initialState);
  
const handleFileUpload = (
  e: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLDivElement>
  ) => {
  e.preventDefault();
  let fileList;
  if (e.type === 'change') {
    fileList = (e.target as HTMLInputElement).files;
  } else {
  fileList = (e as React.DragEvent<HTMLDivElement>).dataTransfer.files;
  }
  const fileArray = Array.from(fileList || []);
  setFormData((current) => ({
    ...current,
    files: [...current.files, ...fileArray],
  }));
  };

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
try {
  await sendEmailForm(formData, 'applicationMail');
  setFormData(initialState);
} catch (error: any) {
  console.log(error.message)
  });
}
};

return(
     <FileInput
        name={fileLabel}
        labelText={fileLabel}
        onChange={handleFileUpload}
        filePreview={formData.files}
        removeFile={removeFile}
        removeAllFiles={removeAllFiles}
        handleDragOver={handleDragOver}
      />
    )

export default ApplicationForm;

I save the uploaded files in the state as an array.

Following the fetch function in lib/api.ts

export const sendEmailForm = async (
data: any,
apiEndpoint: 'applicationMail' | 'contactMail' | 'callbackMail'
) => {
fetch(`/api/${apiEndpoint}`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify(data),
}).then((res) => {
  if (!res.ok)
    throw new Error(`Failed to send email, status code: ${res.status}`);
  return res.json();
});
};

Next.js API applicationMail.ts

import type { NextApiRequest, NextApiResponse } from 'next';
import {
applicationEmailTransporter,
applicationMailOptions,
} from '../../services/nodemailer';
import { generateEmailTemplate } from './../../lib/emailTemplate';

const applicationFormHandler = async (
req: NextApiRequest,
res: NextApiResponse
) => {
const data = req.body;
if (req.method === 'POST') {
if (!data.firstName || !data.lastName || !data.email || !data.message)
  return res.status(400).json({ message: 'Bad request' });
}

try {
  await applicationEmailTransporter.sendMail({
    ...applicationMailOptions,
    ...generateEmailTemplate(data),
    subject: 'New message',
  });
  if (data.email && data.email.length > 0) {
    try {
      await applicationEmailTransporter.sendMail({
        to: data.email,
        from: process.env.NEXT_PUBLIC_APPLICATION_EMAIL,
        subject: 'subject',
        text: `text`,
        html: `<p>html</p>`,
      });
    } catch (error) {
      console.log(error.message)
    }
  }
  return res.status(200).json({ message: 'Success' });
} catch (error: any) {
  return res.status(400).json({ message: error.message });
}
};

export default applicationFormHandler;

Lastly the nodemailer.js for the transporter

import nodemailer from 'nodemailer';


const applicationEmail = process.env.NEXT_PUBLIC_APPLICATION_EMAIL;
const applicationEmailPassword =
process.env.NEXT_PUBLIC_APPLICATION_EMAIL_PASSWORD;

export const applicationEmailTransporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
  user: applicationEmail,
  pass: applicationEmailPassword,
 },
});

export const applicationMailOptions = {
from: applicationEmail,
to: applicationEmail,
attachments: [
  {
    // Retrieve formData.files data from ApplicationForm.tsx 
    // filename: 'test.png',
    // path: './public/assets/test.png',
  },
 ],
};

My Question is if it would be possible to send attachments containing the file data from my ApplicationForm.tsx using just nodemailer or would i need a package like multer?

How would i refactor my current setup to properly send the uploaded files.

Thanks in advance!

nextjs params not available during build

I’m using nextjs 13 with experimental app directory. My app uses dynamic routing like so:

https://app.domain/[itemid]/[slug]

In my [slug] directory, if I create pages.jsx, a server site route, with the following:

export default async function pageComponent ({ params, ...props }) {

    console.log('params': params);
    const data = await afunction(params.itemid);
    ...

The app works as expected when I run as dev. A url such as:

https://app.domain/44/pagetitle

Outputs params.itemid = '44' and params.slug = 'pagetitle' in the console, as I expected.

Problem

I can’t build the app for production. If I run npm run build, it attempts to compile page.jsx and finds that afunction on pageComponent is undefined as it had no params.itemid. A user never targeted a specific url, so no params were generated when it’s building. The params come from dynamic values set in a growing database. The various values in the database may be edited so I don’t want an entirely static page.

Research

Based on the documentation, I’m unsure of how else I’m supposed to handle this. I feel I’m missing a step here but I don’t feel I need to generateStaticParams but perhaps I’m wrong on this one?

Nextjs Framer animation not working as expected

I am using framer motion with Next.JS. I want to create smooth page transition. I have code that work as expected but with pure React https://codesandbox.io/s/animate-page-transition-cgx7f?file=/src/card.component.jsx

When I am using Next.JS Link somehow framer evaluate start transition point for shared item not based on the position of the element on the screen, but on the position of the element on the html

Error when using write() in “react-native-ble-manager” library with status=3

So, I’m trying to send data to BLE device.
My phone and BLE device are already connected.

My function:

const sendCom = async () => {
 const data = utf8Encode('1') // convert data to bytes
 const service = 'fff0'
 const characteristic = 'fff1'
 try {
    await BleManager.retrieveServices(peripheral.id)
    await BleManager.startNotification(peripheral.id, service, characteristic)
    await BleManager.write(peripheral.id, service, characteristic, data)
    console.log(`Sent: ${data}`)
  } catch (error) {
    console.log(`Error writing ${characteristic}: ${error}`)
  }
}

This is error I getting:

Error writing fff1: Error writing 0000fff1-0000-1000-8000-00805f9b34fb status=3

Please help me to resolve this error. I tried to find answer on the internet, but didn’t find.
I also tried this function in different variations for example using Promises with .then() and .catch()

Post to endpoint every minute until attempts run out or successful response

Below I am using the Twit Library and I am trying to post a twitter API endpoint and if I receive a particular 403 message back, I want to try posting to the same API endpoint again. The total attempts I want to try are 10, with one attempt every minute. This works for the first attempt but does not work past that, how do I update this script to do this?

const Twit = require('twit');
const T = new Twit({...}); // configuration object

const attemptTweet = async (tweet) => {
let attempts = 10;
const response = await T.post(
    'statuses/update',
    {
        status: tweet
    },
    (error, data, response) => {
        if (
            error
            && error.code === 187
            && error.message === 'Status is a duplicate.'
        ) {
            attempts = attempts - 1;
            console.log('attempts left: ' + attempts);
            if (attempts === 0) {
                console.log('attempts ran out');
                return;
            }
            setTimeout(async () => {
                console.log('trying again in 1 minute...');
                try {
                    const reattemptResponse = await attemptTweet(tweet);
                    return reattemptResponse;
                } catch (error)  {
                    console.error(error);
                    return {
                        error: error
                    };
                }
            }, 60000);
        } else {
            return;
        }
    }
);
return response;
};

attemptTweet('hello');

How can I filter/find in (casecading) array of arrays json

I’m trying to write js code to find if any item already exits in the array, it makes it a bit tricky. There are multiple items, every item has a zone, every zone has multiple sizes and every size has multiple colors. colors array sometime could be null.

I’m trying to find a way to filter/find item by itemid, zoneid, sizeid and colorid if these all four ids are found then it should be considered as item already exists in the array. But if same color id exist in different size or item then its not a match, here is simplified version of json

[
  {
    "id": 1,
    "title": "Item 1",
    "image": {
      "id": 5,
      "title": "Title image",
    },
    "zone": {
      "id": 3,
      "title": "example title",
      "zone": {
        "id": 1,
        "name": "zome name",
        "zoneCode": 1
      },
      "sizes": [
        {
          "id": 9,
          "SizeName": "Example name",
          "colors": [
            {
              "id": 1,
              "sizeId": 9,
              "itemColor": {
                "id": 1,
                "title": "Color1",
                "code": "#fff"
              }
            },
            {
              "id": 2,
              "sizeId": 9,
              "itemColor": {
                "id": 2,
                "title": "Color2",
                "code": "#f0f"
              }
            }           
          ],
          "itemSize": {
            "id": 1,
            "title": "title",
          },
          "style": {
            "id": 1,
            "name": "None",
          }

        }]
    }
  }
]

and here is how I’m trying to achieve it and looking for nicer and simpler approach.

let itemid = 1
let zoneid = 1        
let sizeid = 1
let colorid = 2

let items = items.filter((item) => {
    item.id == itemid && item.zone.id == zoneid && item.sizes.filter((size) => {
        size.id == sizeid && size.colors.filter((color) => {
            color.id == colorid
        })
    })
})

How to paginate XML responses using digital ocean spaces api?

I am having trouble making sense of the documentation for the DO Spaces API in my fetch request to obtain all records which exceed the max-keys value of 1000 in the response. https://docs.digitalocean.com/reference/api/spaces-api/

I’m hoping to fetch the content without having to use s3 for this task.

const spacesURL = 'https://xxx.sfo3.digitaloceanspaces.com'
const xml = await fetch(
     spacesURL
    ).then(res => res.text())
    const parser = new XMLParser()
    const paths = parser
      .parse(xml)
      ['ListBucketResult']['Contents'].filter(({ Key }: { Key: string }) =>
        Boolean(Key)
      )
      .map(({ Key }: { Key: string }) => Key.trim())

Is there a way to see the JSDocs and Intellisense of a method from a class which is dynamically add by FeatureManager

my goal is to create a class with which all other classes can be manipulated(added, removed, etc…) using my own FeatureManager class. Everything is working fine, but I am having trouble documenting the methods and properties of the custom classes that I use. Not by writing them, but by seeing them.
Would it be possible to see the JSDocs and Intellisense in the example below?

Example: https://pastebin.com/2uXPECnr

The catch is that I do not want to use third-party “libraries” such as Flow, TS, etc. Only pure JavaScript

I’ve tried a lot of things and I’m starting to think it’s not impossible. I tried adding different JSDoc comments in different places and had no results. I tried using type definition types.d.ts but got an error from webpack when I try to import it.

The goal is this: image example