Repetitive Query in MongoDB

I am creating a query in MongoDB which works correctly for me but in the end I have to do an extra grouping to get the response grouped by year. This is the query:

db.sales.aggregate([
  {
    $group: {
      _id: {
        month: {
          $month: "$createdAt"
        },
        year: {
          $year: "$createdAt"
        },
        dayOfWeek: {
            $dayOfWeek: "$createdAt"
        },
        stringDay: { 
            $dateToString: 
            { format: "%Y-%m-%d", date: "$createdAt"}
        },
        week: {
            $isoWeek: "$createdAt"
        }
      },
      total: { $sum: '$total'},
      count: { $sum: 1 },
      totalAverage: { $avg: '$total'}
    }
  },
  { 
    $sort : { 
    "_id.month" : 1 
    } 
  },
  {
    $project: {
      total:  { $round: [ "$total", 2 ] },
      year: "$_id.year",
      date: "$_id.date",
      week: "$_id.week",
      numVentas: "$count",
      month: "$_id.month",
      dayOfWeek: "$_id.dayOfWeek",
      stringDay:"$_id.stringDay",
      count: "$count",
      totalAverage: { $round: [ "$totalAverage", 2 ] },
      stringMonth: {
        $arrayElemAt: [
          [
            "",
            "Jan",
            "Feb",
            "Mar",
            "Apr",
            "May",
            "Jun",
            "Jul",
            "Aug",
            "Sep",
            "Oct",
            "Nov",
            "Dec"
          ],
          "$_id.month"
        ]
      },
      stringWeek: {
        $switch: {
            branches:[
                { case: { $eq: ["$_id.dayOfWeek", 1] }, then: "Lunes" },
                { case: { $eq: ["$_id.dayOfWeek", 2] }, then: "Martes" },
                { case: { $eq: ["$_id.dayOfWeek", 3] }, then: "Miércoles" },
                { case: { $eq: ["$_id.dayOfWeek", 4] }, then: "Jueves" },
                { case: { $eq: ["$_id.dayOfWeek", 5] }, then: "Viernes" },
                { case: { $eq: ["$_id.dayOfWeek", 6] }, then: "Sábado" },
                { case: { $eq: ["$_id.dayOfWeek", 7] }, then: "Domingo" }
            ],
            default: "Día desconocido"
            }
        }
    }
  },
  {
    $group: {
        _id:  { month: "$stringMonth", year: "$year"},
        count: { $sum: "$count" },
        total: { $sum: "$total" },
        totalAverage: { $sum: "$totalAverage" },
        sales: {
            $push: {
                numberDay: "$dayOfWeek",
                stringWeek: "$stringWeek",
                date: "$stringDay",
                total: "$total",
                count: "$count",
                totalAverage: { $round: [ "$totalAverage", 2 ] }  
            }
        }
    }
  },
  {
    $group: {
        _id: "$_id.year",
        monthsWithSales: { $sum: 1 },
        count: { $sum: "$count" },
        total: { $sum: "$total" },
        totalAverage: { $sum: "$totalAverage" },
        sales: {
            $push: {
                mes: "$_id.month",
                count: "$count",
                total: "$total",
                totalAverage: "$totalAverage",
                sales:"$sales"
            }
        }
    }
  }
  
])

And I get this response:


[
  {
    "_id": 2022,
    "monthsWithSales": 4,
    "count": 57,
    "total": 22324.8,
    "totalAverage": 7765.799999999999,
    "sales": [
      {
        "mes": "Oct",
        "count": 10,
        "total": 1936,
        "totalAverage": 1233.6,
        "sales": [
          {
            "numberDay": 6,
            "stringWeek": "Sábado",
            "date": "2022-10-21",
            "total": 526.8,
            "count": 3,
            "totalAverage": 175.6
          },
          {
            "numberDay": 1,
            "stringWeek": "Lunes",
            "date": "2022-10-02",
            "total": 85.6,
            "count": 1,
            "totalAverage": 85.6
          },
          {
            "numberDay": 7,
            "stringWeek": "Domingo",
            "date": "2022-10-22",
            "total": 526.8,
            "count": 3,
            "totalAverage": 175.6
          },
          {
            "numberDay": 3,
            "stringWeek": "Miércoles",
            "date": "2022-10-04",
            "total": 180,
            "count": 1,
            "totalAverage": 180
          },
          {
            "numberDay": 4,
            "stringWeek": "Jueves",
            "date": "2022-10-12",
            "total": 531.2,
            "count": 1,
            "totalAverage": 531.2
          },
          {
            "numberDay": 3,
            "stringWeek": "Miércoles",
            "date": "2022-10-25",
            "total": 85.6,
            "count": 1,
            "totalAverage": 85.6
          }
        ]
      },
      {
        "mes": "Nov",
        "count": 7,
        "total": 2205.2,
        "totalAverage": 1014.8,
        "sales": [
          {
            "numberDay": 4,
            "stringWeek": "Jueves",
            "date": "2022-11-02",
            "total": 526.8,
            "count": 3,
            "totalAverage": 175.6
          },
          {
            "numberDay": 6,
            "stringWeek": "Sábado",
            "date": "2022-11-25",
            "total": 171.2,
            "count": 2,
            "totalAverage": 85.6
          },
          {
            "numberDay": 7,
            "stringWeek": "Domingo",
            "date": "2022-11-12",
            "total": 1507.2,
            "count": 2,
            "totalAverage": 753.6
          }
        ]
      },
      {
        "mes": "Dec",
        "count": 33,
        "total": 12587.6,
        "totalAverage": 4074.5,
        "sales": [
          {
            "numberDay": 3,
            "stringWeek": "Miércoles",
            "date": "2022-12-06",
            "total": 850,
            "count": 1,
            "totalAverage": 850
          },
          {
            "numberDay": 6,
            "stringWeek": "Sábado",
            "date": "2022-12-02",
            "total": 8737.6,
            "count": 25,
            "totalAverage": 349.5
          },
          {
            "numberDay": 7,
            "stringWeek": "Domingo",
            "date": "2022-12-10",
            "total": 900,
            "count": 1,
            "totalAverage": 900
          },
          {
            "numberDay": 1,
            "stringWeek": "Lunes",
            "date": "2022-12-04",
            "total": 200,
            "count": 1,
            "totalAverage": 200
          },
          {
            "numberDay": 2,
            "stringWeek": "Martes",
            "date": "2022-12-05",
            "total": 500,
            "count": 1,
            "totalAverage": 500
          },
          {
            "numberDay": 5,
            "stringWeek": "Viernes",
            "date": "2022-12-08",
            "total": 250,
            "count": 2,
            "totalAverage": 125
          },
          {
            "numberDay": 4,
            "stringWeek": "Jueves",
            "date": "2022-12-07",
            "total": 250,
            "count": 1,
            "totalAverage": 250
          },
          {
            "numberDay": 6,
            "stringWeek": "Sábado",
            "date": "2022-12-09",
            "total": 900,
            "count": 1,
            "totalAverage": 900
          }
        ]
      },
      {
        "mes": "Sep",
        "count": 7,
        "total": 5596,
        "totalAverage": 1442.8999999999999,
        "sales": [
          {
            "numberDay": 2,
            "stringWeek": "Martes",
            "date": "2022-09-12",
            "total": 5069.2,
            "count": 4,
            "totalAverage": 1267.3
          },
          {
            "numberDay": 6,
            "stringWeek": "Sábado",
            "date": "2022-09-02",
            "total": 526.8,
            "count": 3,
            "totalAverage": 175.6
          }
        ]
      }
    ]
  },
  {
    "_id": 2021,
    "monthsWithSales": 1,
    "count": 2,
    "total": 608,
    "totalAverage": 608,
    "sales": [
      {
        "mes": "Dec",
        "count": 2,
        "total": 608,
        "totalAverage": 608,
        "sales": [
          {
            "numberDay": 1,
            "stringWeek": "Lunes",
            "date": "2021-12-12",
            "total": 171.2,
            "count": 1,
            "totalAverage": 171.2
          },
          {
            "numberDay": 4,
            "stringWeek": "Jueves",
            "date": "2021-12-22",
            "total": 436.8,
            "count": 1,
            "totalAverage": 436.8
          }
        ]
      }
    ]
  }
]

It is correct, but as you can see at the end I make two groups to obtain the data grouped by year and then the sales array grouped by month.

Is there any way to improve this query without so much grouping?

How to optimize Web App loading times when using multiple google spreadsheets

I have the following code that connects to a single google sheet and different tabs, and the web app load times are fast (almost 3-5 seconds). However, I need to connect to not one sheet, but 23 different ones (with different Urls). When I make the change (to the second code that I share) the loading times of the web app are too slow, very very slow (between 4 to 5 minutes).
How could I make the loading and response times of the Web App faster, like when I use a single URL, but now using 23 different URLs? Is there any other alternative?
I can only use pure javascript. I’m new to this so please bear with me. Any help will be greatly appreciated. Thanks in advance for your time and help.

SAME GOOGLESHEETS DOCUMENT (SAME URL, DIFFERENT TABS)
WITH THIS SCRIPT, THE WEB APP LOADS QUICKLY

var ss_operations_0 = SpreadsheetApp.openByUrl("URL0");

var sheetoperations1 = ss_operations_0.getSheetByName("SHEET1");
var sheetoperations2 = ss_operations_0.getSheetByName("SHEET2");
var sheetoperations3 = ss_operations_0.getSheetByName("SHEET3");
var sheetoperations4 = ss_operations_0.getSheetByName("SHEET4");
var sheetoperations5 = ss_operations_0.getSheetByName("SHEET5");
var sheetoperations6 = ss_operations_0.getSheetByName("SHEET6");
var sheetoperations7 = ss_operations_0.getSheetByName("SHEET7");
var sheetoperations8 = ss_operations_0.getSheetByName("SHEET8");
var sheetoperations9 = ss_operations_0.getSheetByName("SHEET9");
var sheetoperations10 = ss_operations_0.getSheetByName("SHEET10");
var sheetoperations11 = ss_operations_0.getSheetByName("SHEET11");
var sheetoperations12 = ss_operations_0.getSheetByName("SHEET12");
var sheetoperations13 = ss_operations_0.getSheetByName("SHEET13");
var sheetoperations14 = ss_operations_0.getSheetByName("SHEET14");
var sheetoperations15 = ss_operations_0.getSheetByName("SHEET15");
var sheetoperations16 = ss_operations_0.getSheetByName("SHEET16");
var sheetoperations17 = ss_operations_0.getSheetByName("SHEET17");
var sheetoperations18 = ss_operations_0.getSheetByName("SHEET18");
var sheetoperations19 = ss_operations_0.getSheetByName("SHEET19");
var sheetoperations20 = ss_operations_0.getSheetByName("SHEET20");
var sheetoperations21 = ss_operations_0.getSheetByName("SHEET21");
var sheetoperations22 = ss_operations_0.getSheetByName("SHEET22");
var sheetoperations23 = ss_operations_0.getSheetByName("SHEET23");

DIFFERENT GOOGLESHEETS DOCUMENTS (DIFFERENT URLS)
WITH THIS SCRIPT, THE WEB APP LOADS VERY SLOW

var ss_operations_1 = SpreadsheetApp.openByUrl("URL1");
var ss_operations_2 = SpreadsheetApp.openByUrl("URL2");
var ss_operations_3 = SpreadsheetApp.openByUrl("URL3");
var ss_operations_4 = SpreadsheetApp.openByUrl("URL4");
var ss_operations_5 = SpreadsheetApp.openByUrl("URL5");
var ss_operations_6 = SpreadsheetApp.openByUrl("URL6");
var ss_operations_7 = SpreadsheetApp.openByUrl("URL7");
var ss_operations_8 = SpreadsheetApp.openByUrl("URL8");
var ss_operations_9 = SpreadsheetApp.openByUrl("URL9");
var ss_operations_10 = SpreadsheetApp.openByUrl("URL10");
var ss_operations_11 = SpreadsheetApp.openByUrl("URL11");
var ss_operations_12 = SpreadsheetApp.openByUrl("URL12");
var ss_operations_13 = SpreadsheetApp.openByUrl("URL13");
var ss_operations_14 = SpreadsheetApp.openByUrl("URL14");
var ss_operations_15 = SpreadsheetApp.openByUrl("URL15");
var ss_operations_16 = SpreadsheetApp.openByUrl("URL16");
var ss_operations_17 = SpreadsheetApp.openByUrl("URL17");
var ss_operations_18 = SpreadsheetApp.openByUrl("URL18");
var ss_operations_19 = SpreadsheetApp.openByUrl("URL19");
var ss_operations_20 = SpreadsheetApp.openByUrl("URL20");
var ss_operations_21 = SpreadsheetApp.openByUrl("URL21");
var ss_operations_22 = SpreadsheetApp.openByUrl("URL22");
var ss_operations_23 = SpreadsheetApp.openByUrl("URL23");

var sheetoperations1 = ss_operations_1.getSheetByName("SHEET1");
var sheetoperations2 = ss_operations_2.getSheetByName("SHEET1");
var sheetoperations3 = ss_operations_3.getSheetByName("SHEET1");
var sheetoperations4 = ss_operations_4.getSheetByName("SHEET1");
var sheetoperations5 = ss_operations_5.getSheetByName("SHEET1");
var sheetoperations6 = ss_operations_6.getSheetByName("SHEET1");
var sheetoperations7 = ss_operations_7.getSheetByName("SHEET1");
var sheetoperations8 = ss_operations_8.getSheetByName("SHEET1");
var sheetoperations9 = ss_operations_9.getSheetByName("SHEET1");
var sheetoperations10 = ss_operations_10.getSheetByName("SHEET1");
var sheetoperations11 = ss_operations_11.getSheetByName("SHEET1");
var sheetoperations12 = ss_operations_12.getSheetByName("SHEET1");
var sheetoperations13 = ss_operations_13.getSheetByName("SHEET1");
var sheetoperations14 = ss_operations_14.getSheetByName("SHEET1");
var sheetoperations15 = ss_operations_15.getSheetByName("SHEET1");
var sheetoperations16 = ss_operations_16.getSheetByName("SHEET1");
var sheetoperations17 = ss_operations_17.getSheetByName("SHEET1");
var sheetoperations18 = ss_operations_18.getSheetByName("SHEET1");
var sheetoperations19 = ss_operations_19.getSheetByName("SHEET1");
var sheetoperations20 = ss_operations_20.getSheetByName("SHEET1");
var sheetoperations21 = ss_operations_21.getSheetByName("SHEET1");
var sheetoperations22 = ss_operations_22.getSheetByName("SHEET1");
var sheetoperations23 = ss_operations_23.getSheetByName("SHEET1");


I want to be able to delete an object from the api and re render the function without having to manually refresh the page, how can I do that?

const Notes = () => {
  const history = useNavigate();

  const [apiData, setApiData] = useState([]);

  useEffect(() => {
    axios
      .get(`https://6390acc765ff4183111b53e9.mockapi.io/notes`)
      .then((getData) => {
        setApiData(getData.data);
      });
  }, []);

  const onDelete = (id) => {
    axios
      .delete(`https://6390acc765ff4183111b53e9.mockapi.io/notes/${id}`)
      .then(() => {
        history("/notes");
      });
  };

This way I can delete the note that i fetched earlier, but it still appears on the screen until I refresh manually. It doesn’t also go to /notes because i am already on /notes

How do I stop the timer without the user noticing?

I’m having a problem with the countdown tool on this page

https://codepen.io/SitePoint/pen/NWxKgxN

initializeClock('clockdiv', deadline);

I can add a new timer as I want, but the old countdown continues. How can I stop or delete the current countdown?

initializeClock(‘clockdiv’, deadline); somehow I added new timer but 2 timers are running at the same time.

filter mongoose query by year

i need to give the api user the option to filter the wine query by year, but when no year is specified mongoose should not return an empty array
same with the price property

http://localhost:1234/api/wine?year=2010
should return wines from 2010

http://localhost:1234/api/wine
should return all wines (actually 10, because of the limit)

i was able to implement other filters as you can see below
btw, is this the best way to do it?

thank you

controller

  getWines: async (req, res) => {
    try {
      const types = ['red', 'white'];
      let {
        limit = 10,
        page = 1,
        // sort = 'asc',
        search = '',
        type = 'all',
        year = undefined,
      } = req.query;
      if (page === '0') {
        return res.json({ error: 'Invalid page' });
      }
      type === 'all' ? (type = [...types]) : (type = [req.query.type]);
      const response = await Wine.find({
        name: { $regex: search, $options: 'i' },
      })
        .where('type')
        .in(type)
        // .where('year')
        // .equals(parseInt(year))
        // .sort(sort)
        .limit(limit)
        .skip((parseInt(page) - 1) * limit);
      res.json(response);
    } catch (error) {
      console.error(error);
    }
  },

documents sample

[{
"_id": "63952372129acf895c427240",
        "name": "Chateau Leoville Barton",
        "year": 2010,
        "type": "red",
        "domain": "Saint-Julien",
        "quantity": 750,
        "price": 169,
        "quality": 100,
        "image": <<<<LONG_URL>>>>
},
{
        "_id": "639523e7129acf895c42c238",
        "name": "Chateau La Mission Haut Brion",
        "year": 2014,
        "type": "red",
        "domain": "Pessac-Leognan",
        "quantity": 750,
        "price": 219,
        "quality": 94,
        "image": <<<<LONG_URL>>>>
}]

Getting the error “Exception: The starting column of the range is too small.” in google sheets

Here is the code

 
/**
 * @OnlyCurrentDoc
*/
 

const RECIPIENT_COL  = "Recipient";
const EMAIL_SENT_COL = "Email Sent";
 
/** 
 * Creates the menu item "Mail Merge" for user to run scripts on drop-down.
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Mail Merge')
      .addItem('Send Emails', 'sendEmails')
      .addToUi();
}
 

function sendEmails(subjectLine, sheet=SpreadsheetApp.getActiveSheet()) {
  // option to skip browser prompt if you want to use this code in other projects
  if (!subjectLine){
    subjectLine = Browser.inputBox("Mail Merge", 
                                      "Type or copy/paste the subject line of the Gmail " +
                                      "draft message you would like to mail merge with:",
                                      Browser.Buttons.OK_CANCEL);
                                      
    if (subjectLine === "cancel" || subjectLine == ""){ 
    // if no subject line finish up
    return;
    }
  }
  
  const emailTemplate = getGmailTemplateFromDrafts_(subjectLine);
  
  const dataRange = sheet.getDataRange();

  const data = dataRange.getDisplayValues();

  const heads = data.shift(); 
  
  const emailSentColIdx = heads.indexOf(EMAIL_SENT_COL);
  
  const obj = data.map(r => (heads.reduce((o, k, i) => (o[k] = r[i] || '', o), {})));


  const out = [];

  obj.forEach(function(row, rowIdx){
    // only send emails is email_sent cell is blank and not hidden by filter
    if (row[EMAIL_SENT_COL] == ''){
      try {
        const msgObj = fillInTemplateFromObject_(emailTemplate.message, row);

        GmailApp.sendEmail(row[RECIPIENT_COL], msgObj.subject, msgObj.text, {
          htmlBody: msgObj.html,
          // bcc: '[email protected]',
          // cc: '[email protected]',
          // from: '[email protected]',
          // name: 'name of the sender',
          // replyTo: '[email protected]',
          // noReply: true, // if the email should be sent from a generic no-reply email address (not available to gmail.com users)
          attachments: emailTemplate.attachments,
          inlineImages: emailTemplate.inlineImages
        });
        // modify cell to record email sent date
        out.push([new Date()]);
      } catch(e) {
        // modify cell to record error
        out.push([e.message]);
      }
    } else {
      out.push([row[EMAIL_SENT_COL]]);
    }
  });
  

  sheet.getRange(2, emailSentColIdx+1, out.length).setValues(out);
  

I am not entirely sure why that error is showing up. It is for sure in the following line of code so I changed it a bit from

 sheet.getRange(2, emailSentColIdx+1, out.length).setValues(out);

to

 sheet.getRange(2, emailSentColIdx+2, out.length).setValues(out);

It completed the script but would not actually send those emails/carry out the functions intended.
When I output Logger.log(out), I get the following:

[[null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null]]

If you can help me figure out what I am doing wrong, it would be greatly appreciated.

Convert date string to MM DD in react

I have a date string that is returned from API in an object. I need to reformat it so instead of “2022-12-13T06:00Z” it would read “December 13”. The object holds utcStart as “2022-12-13T06:00Z”. Currently the below displays as “2022-12-13T06:00Z”

const eventDates = useRecoilValue(eventDatesState);
return (
    <Grid item xs={12}>
        eventDates.map (data =>(
            <ListItem>
                <span className="date">{eventDates.utcStart}</span>
            </ListItem>
        ))
    </Grid>
)

Since it is in a map function, I don’t know how to do this for each one.This doesn’t work

<span className="date">{new Date(calendarContent.utcStart)}</span>

unshift and push inside a loop in Javascript, infinite loop javascript

I’m a beginner student and I’m try to get some information from “user” using the prompt() function, and then throw this information in an array. I need to use the loop FOR and the WHILE to solve this problem.

This is my code:

let allEmployeess = Number(prompt("How many employees in the company?"));

let employee = new Array(allEmployeess);
let contador = 1;

for (let i = 0; i <= employee.length; i++) {
  let colaborador = {
    name: prompt("Employee name:"),
    salary: Number(prompt("What is the salary amount??"))
  }

  employee.unshift(colaborador);
}

This isn’t working and I’m falling into an infinite loop.

I suppose this happens because the unshift(and push) method, return the new lenght of the array, and maybe I’m increasing the array leaving it always bigger than the counter.

What can I do to solve this?

ReferenceError: X is not defined (using async/await)

I am trying to build a program that should be able to update entries in a Firebase database. It should have a method that handles updating a single top-level node, and a method that handles updating all top-level nodes (max # of top-level nodes is 10). The data that I am inserting into the firebase database comes from an online API.

I am pretty new to node.js and javascript and I believe I have gotten myself caught in a mess of async, awaits, and promises, that I presumably don’t understand fully yet.

This is my Firebase manager class:

import { initializeApp } from "firebase/app";
import { getDatabase, ref, remove, set, onValue } from "firebase/database";
import { ApiManager } from './api_manager.js'; // Fetching data from API here works as intended AFAIK
import { idList } from '../data/data.js';
import { DateManager } from "./date_manager.js";

export class FirebaseManager {
    constructor() {
        this.firebaseConfig = {
            ...
        };
        this.app = initializeApp(this.firebaseConfig);
        this.db = getDatabase();
    }

    /* Only update data for a single day (minimizing API calls) */
    async updateSingle(day, apiManager) {
        idList.forEach(async id => {
            let reference = ref(this.db, `${day}/${id}`);
            let data = await apiManager.getDataApi(day, id, apiManager.season);
            set(reference, data);
        });

        return;
    }

    /* Update and insert match info for the next 7 days
    nested by date in firebase RT database */
    async updateAll(datesArr, apiManager) {
        datesArr.forEach(async date => {
            await updateSingle(date, apiManager);
        });

        return;
    }

    /* Remove date child if it is in the past (e.g. not in the date array) */
    removeOldData(datesArr) {
        let rootRef = ref(this.db, "/");
        let foundOldDates = false;

        onValue(rootRef, (snapshot) => {
            snapshot.forEach(date => {
                if(!datesArr.includes(date.key)) {
                    let refOld = ref(this.db, `${date.key}/`);
                    remove(refOld)
                    foundOldDates = true;
                }
            })
        }, {
        onlyOnce: true
        });

        return foundOldDates;
    }
}

Now, based on the updateAll()– and updateSingle()-methods, I would like to every 3 minutes update my database from a seperate .js file. I do this here:

import { FirebaseManager } from "./firebase_manager.js";
import { ApiManager } from './api_manager.js';
import { DateManager } from './date_manager.js';

async function main() {

    // initialize managers
    let apiManager = new ApiManager();
    let dateManager = new DateManager();
    let firebaseManager = new FirebaseManager();

    await apiManager.getCurrentSeason();
    await firebaseManager.updateAll(dateManager.dates, apiManager); // Error on FirebaseManager's updateSingle() happens here

    let countDaily = 0;
    let dateRemoved = false;

    while(true) {
        // update dates in class
        dateManager.update(); 

        // update season in class once every 24 hrs 
        // countDaily increments every 4 min. 1440 min in a day. 1440 / 4 = 360
        if(countDaily >= 360) {
            await apiManager.getCurrentSeason();
            countDaily = 0; 
        }

        // update info for today
        await firebaseManager.updateSingle(
            dateManager.getToday(),
            apiManager);

        // remove old date, and if something is removed update/add info for all days
        dateRemoved = firebaseManager.removeOldData(dateManager.dates);
        if(dateRemoved) {
            await firebaseManager.updateAll(
                dateManager.dates, 
                apiManager);
            dateRemoved = false;
        }

        // increment
        countDaily++;

        // sleep 3 minutes
        // (max # of requests / # of requests required to update single day)
        await new Promise(r => setTimeout(r, 240000)); 
    }
}

main();

Running this gives me the following error:

ReferenceError: updateSingle is not defined
    at file:///c:/Users/x/Projects/backend/src/firebase_manager.js:37:13
    at Array.forEach (<anonymous>)
    at FirebaseManager.updateAll (file:///c:/Users/x/Projects/backend/src/firebase_manager.js:36:18)
    at main (file:///c:/Users/x/Projects/backend/src/app.js:25:31)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

I have tried adding and removing async/await several places but to no avail. The logic of writing to my Firebase database works, as I can do without using my updateSingle()-method, so I am unsure what I am missing. All help and pointers in the right direction are appreciated.

How do libraries to provide users a bindData function?

I need to copy the behaviour of, for example, the “create” function of Axios:

// fileOne.js
import axios from 'axios';


const instance = axios.create({
  baseURL: 'https://some-domain.com/api'
});

Then to use that baseURL in another file, with another function like this:

// fileTwo.js
import axios from 'axios';

axios.get('/user/12345'); // https://some-domain.com/api/user/12345

Getting this as result:
https://some-domain.com/api/user/12345

How does Axios to bind the baseURL data in his library.

I’m looking that library but i don’t understand how they do that.

JavaScript if/else statement, one has ajax, the other does not, but both should redirect to same place

I have a standard form with fields. One of those fields is a file upload. The form is processed via ajax and in the success block, IF there are attached files, I need to make another ajax call to upload the file. This is where I’m struggling. If an upload needs to be done, I execute the if/ block, perform ajax, then on ajax success, redirect. In the /else block, I don’t need to perform any ajax, so I can immediately redirect. I don’t like having this redirect twice as it is not DRY. I know I can instead use a function in each of these places, then only have the redirect once, but that still seems to violate the DRY standard since I’m still calling the function twice.

Is there a better way to write this?

          if (files.length > 0) {

            readFile(files[0],function(filestring){
              var fileObj = new Object();
                  fileObj.file = filestring.split(";base64,")[1];
                  fileObj.fullFileName = document.getElementById("file").files[0].name;
                  fileObj.fileName = fileObj.fullFileName.split(".")[0];
                  fileObj.ext = fileObj.fullFileName.split(".")[1];
                  fileObj.leadid = resp.leadid;

                  doAjax(fileObj,endpoints.file).then(function(resp){
                    
                    window.location.href = "returnURL";
                  });

            });              
          }else{
              window.location.href = "returnURL";
          }

I cannot think of a better/cleaner way to write this and I am not sure how to search for this on Google, since I’m not sure what the correct terminology would be to describe this problem.

Javascript: button onclick function which will increase the HTML output number per click

Want to create a small application which have the function of counter and alarm. So there is two button, -1 and +1. When click the button, the number will continuesly change according to the time you click. So if click -1 button once, it will shows 0-1, if click -1 again, it will shows 0-2. Button

I try to use localstorage command to record each time when the button is clicked. I wondered is there other easier way to solve it.

Keeping escaped unicode caracters

I have an input JSON like this:

{"source":"Subject: NEED: 11/5 BNA-MSL u2013 1200L Departure - 1 Pax"}

I read it with JSON.parse and it reads the u2013 as , which is fine for display in my app.

However, I need to export again the same JSON, to send it down to some other app. I want to keep the same format and have back the u2013 into the JSON. I am doing JSON.stringify, but it keeps the in the output.

Any idea what I could do to keep the u syntax?

Delay Intervals After Each Loop in JQuery

I’m looking at setting a 2-3 second delay on a sprite animation. How do I pause each interval/loop in jquery using the code below?

var imgWidth = 48;
var numImgs = 60;
var cont = 0;

var animation = setInterval(function() {
  var position = -1 * (cont * imgWidth);
  $('#container').find('img').css('margin-left', position);

  cont++;
  if (cont == numImgs) {
    cont = 0;
  }
}, 18);
#container {
  width: 48px;
  height: 48px;
  display: block;
  overflow: hidden;
}

#container img {
  width: 2880px;
  height: 48px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <img src="https://visualcraftsman.com/doh/rdWaitAll.png" alt="My super animation" />
</div>

fiddle