Typescript – how to get interface handle single or multiple objects

I have a question in regards to extending an interface to allow duplicate fields. Basically I need to create 2 requests. One request handles one event, the other request handles 2 events.

Example:

One event request:

events[
{
  "name": "EventOne"
  "description": EventOne Description
}
]

Two events request:

events[
{
  "name": "EventOne"
  "description": EventOne Description
},
{
  "name": "EventTwo"
  "description": EventTwo Description
}
]

So I have a method then sends a request like so:

export function performRequest(params: IEvent) {
  return request(test)
    .post(`/events`)
    .send(params);

I then have two interfaces. One deals with a single request object (IEventDetails), the other extends the IEventDetails and handles the two events request which is known as IMultiEventDetails:

interface IEvent {
  events: [IEventDetails];
}

interface IEventDetails {
name?: string;
description?: string;
}

interface IMultiEventDetails extends IEventDetails{
name?: string;
description?: string;
}

Now when I call on my requests, it works for the single event, but not for the multi event as it gives me the error:

Source has 2 element(s) but target allows only 1

When I call my requests:

Below works:

const response = await performRequest({
events[{
      name: "EventOne"
      description: "EventOne Description"
}]
...

Below errors:

    const response = await performRequest({
    events[{
          name: "EventOne"
          description: EventOne Description
    },
    {
          name: "EventTwo"
          description: EventTwo Description
    }]
    ...

This makes sense as I am not calling on the IMultiEventDetails. I am trying to avoid creating one method to call on single event and another method to call on multi event. So it there a way in order to call on IEvent and have it to be able to handle single or multi event requests?

Convert FormData to json with grouped properties

I have form, let’s say:

<form action="bla">
    <div>
        <input name="form[row1][foo]"
        <input name="form[row1][bar]"
    </div>
    <div>
        <input name="form[row2][foo]"
        <input name="form[row2][bar]"
    </div>
    <div>
        <input name="form[row3][foo]"
        <input name="form[row3][bar]"
    </div>
</form>

I want to convert that FormData to json but when I do that

var formData = new FormData(myForm);
var jsonData = Object.fromEntries(formData.entries());

what I get is an object like:

{
    "form[row1][foo]": "foo1",
    "form[row1][bar]": "bar1",
    "form[row2][foo]": "foo2",
    "form[row2][bar]": "bar2",
    "form[row3][foo]": "foo3",
    "form[row3][bar]": "bar3"
}

but what I want is something like this:

{
    "form": {
        "row1": {
            "foo": "foo1",
            "bar": "bar1"
        },
        "row2": {
            "foo": "foo2",
            "bar": "bar2"
        },
        "row3": {
            "foo": "foo3",
            "bar": "bar3"
        },
    }

Is that possible and how?

Javascript calculator string multiple operations

I am trying to complete the Odin project calculator:
https://www.theodinproject.com/lessons/foundations-calculator

I can get the basic functionality to work, for example 12+7=19 etc.

My problem is getting the following to work:

Users should be able to string together several operations and get the right answer, with each pair of numbers being evaluated at a time. For example, 12 + 7 – 5 * 3 = should yield 42.

If I do 12+7, then press =, then 19-5 then press =, etc, it works, but when doing the entire string in one operation doesn’t work (unless every number is added or multiplied)

Please can someone point out what is wrong in my program or how you would recommend fixing it:

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <script src="js.js" defer></script>
    <title>Calculator</title>

    <div class="container1">
        <div class="btn">

            <div class="boxed">
                0
              </div>
              <div class="boxed1">
                0
              </div>



              <div class="row0">

                <button class="bts ac" type="button"onclick=>AC</button>
                <button class="bts ac2" type="button"onclick="deleteLast()">C </button>
                
            </div>

            <div class="row1">

                <button class="bts num" type="button">7</button>
                <button class="bts num" type="button">8 </button>
                <button class="bts num" type="button">9 </button>
                <button class="bts ops" type="button">+ </button>
            </div>

            <div class="row2">
                <button class="bts num" type="button">4 </button>
                <button class="bts num" type="button">5 </button>
                <button class="bts num" type="button">6</button>
                <button class="bts ops"     type="button">- </button>
            </div>
            <div class="row3">
                <button class="bts num" type="button">1 </button>
                <button class="bts num" type="button">2 </button>
                <button class="bts num" type="button">3 </button>
                <button class="bts ops" type="button">x </button>
            </div>

            <div class="row4">

                <button class="bts num zero" type="button">0 </button>
                <button class="bts num" type="button">. </button>
                <button class="bts equ" type="button">= </button>
                <button class="bts ops" type="button">/ </button>
            </div>

        </div>
    </div>


</head>

<body>

</body>

</html>

CSS:

.container1{
    margin-top: 100px;
    display: flex;
    justify-content: center;
    
}

.btn{
    border-style: double;
    padding-top: 40px;
    padding-left: 10px;
    padding-right: 14px;
    padding-bottom: 10px;
}



.bts{
    
    font-size: 24px;
    width: 50px;
    margin-left: 4px;
    margin-bottom: 4px;
}

.boxed, .boxed1 {
    border: 2px solid black;
    width: 212px;
    margin-left: 4px;
    margin-bottom: 40px;
    height: 50px;
    font-size:40px;
    text-align: right;
    padding-right: 10px;
  }


.ac{
      width: 108px;
      margin-bottom: 10px;

  }

.ac2{
    width: 108px;
    margin-bottom: 10px;
}

Javascript:

const numButtons = document.querySelectorAll('.num');
const opsButtons = document.querySelectorAll('.ops');
const displayRow = document.querySelector('.boxed1');
const displayRow0 = document.querySelector('.boxed');
const equalButton = document.querySelector('.equ');
const clearAll = document.querySelector('.ac');
let CurrentNum = '';
let previousNum = '';
let operationState = null;

function calculate() {

    let previous = parseFloat(previousNum);
    let current = parseFloat(CurrentNum);
    let result;
    if (operationState == '+') {
        result = previous + current;

    } else if (operationState == '-') {
        result = previous - current;

    } else if (operationState == 'x') {
        result = previous * current;

    } else if (operationState == '/') {
        result = previous / current;

    }

    console.log(previous);
    console.log(current);
    CurrentNum = result;
    previousNum = '';
    operation = null;
    
}

function buttonCont() {

    numButtons.forEach((button) => {

        button.addEventListener('click', () => {
            if (CurrentNum == 0) {
                CurrentNum = '';
            }
            if (button.innerText == "." && CurrentNum.includes(".")) return;
            CurrentNum += (button.innerText);
            refreshDisplay();
            console.log(CurrentNum);
        });
    });

    opsButtons.forEach((button) => {

        button.addEventListener('click', () => {
            operationState = (button.innerText);
            operate();
            refreshDisplay();
            
            console.log(operationState);


        });
    });

    equalButton.addEventListener('click', () => {
        calculate();
        refreshDisplay();
    });

    clearAll.addEventListener('click', () => {
        CurrentNum = 0;
        previousNum = '';
        operation = null;
        refreshDisplay();
    });


}

function operate() {
    if (CurrentNum == "") return;

    if (previousNum !== "" && operationState !== null) {
        calculate();
    }
    previousNum = CurrentNum + operationState;
    CurrentNum = '';

}

function refreshDisplay() {
    displayRow.textContent = CurrentNum;
    displayRow0.textContent = previousNum;
}


buttonCont();

Thank you.

fs.writefilesync does not work in a container

So basically the commands works on visual code with node, all nice and good. but when putting up a
Dockerfile and pushing everything into a container, it doesn’t write into the file specified – even when it’s created WITH the container (file exists before).

any reason for that?

and if it’s not doable, is there any other way to make my NodeJS code write into a file within a container, or create files within the container?

thanks in advance

React: How to display times in different time zones using the offset value

I am trying to display the current moment in different time zones. I have tried to use native javascript and the moment-js package but it seems you require the time zone name (ex. “America/Toronto”) to display the information I want. The problem is that the information I currently have is the timestamp in string format (see below for string format) from the desired timezone, and the city the timestamp belongs to. The problem with using the city to create my tz value is that one of the cities I want to display isn’t in the IANA tz database (Calgary).

String timestamp:

2022-04-26T14:19:42.8430964-04:00

As can be seen I do have the time offset and I was hoping there was a way to convert this string in js to a Date object and then display the time using the offset in the correct time zone.

Note what I want to display is the following format:

12:19 pm MT

I know I could just parse out the string but I feel like this isn’t the best practice, however I may be wrong.

TypeORM: convert nested objects in JSON form into entities

I’m using Nest.JS and TypeORM. I have two entity types: File and Folder (As you can imagine, they represent files and folders on a hard drive).

Example of Folder entity:

    {
        id: 'aaa',
        name: 'home',
        childFolders: [],
        files: []
    }

example of File entity:

    {
        id: 'iii',
        name: 'spreadsheet.csv',
        size: 236434,
    }

I have JSON from a DB which represents filesystem structure structure. For example:

    {
        id: 'aaa',
        name: 'home',
        childFolders: [
            {
                id: 'bbb',
                name: 'bob',
                childFolders: [],
                files: [
                    {
                        id: 'iii',
                        name: 'spreadsheet.csv',
                        size: 236434,
                    }
                ]
            }
        ],
        files: []
    }

I am building an opengraph API to be able to search for files/folders. If I want to convert this JSON into a collection of folder and file entities, will I have to loop recursively and build these entities manually? Or is there an easier way to do that?

Thank you so much for any insight you can provide.

Vue watch deep object and get the changed key

Is there a way in Vue to watch a deeply nested object and get the changed keys, not the values?

Here’s a problem I’ve stumbled upon:
I have a table consisting of thousands of objects. User can click on an object, open a modal based on this object and onSubmit it will send an API call with the object user’ve edited and thus rewrite the existing object in DB with it (you can’t change a particular field with this API, you need to rewrite the entire object with a new one based on its previous version). It is very simple when dealing with single object editing, yet good days don’t last and now I need to implement a batch editing – you pick the necessary objects, open a single form, make changes and onSubmit you rewrite not a single one but all these objects in DB with edited fields. The problem here is that objects may have different values and I need to preserve them by changing only the ones edited in the modal.

What I do now is I loop through the one of the original objects and the object in the modal, comparing their fields and collecting keys of fields that are not equal. Since the objects are very deeply nested you may imagine the ifs and }}} stairs I’m having. Anyway I get the changed fields this way and in my API calls I send objects with their not changed fields preserved and new fields updated though it looks too verbose.
I’m using Vue in my project and this is why the idea of a watcher came to my mind, yet I cannot find the implementation that meets my need.

Javascript: comparing two different arrays: unexpected behavior checking if they’re identical

I’m experiencing unexpected behavior when comparing two arrays in Javascript. I’m using the functional library ramda.js in my project to determine if two arrays are equal using equal(a, b), but I’ve also implemented the check by hand for sanity (const arrEq = (arr1, arr2) => arr1.length === arr2.length && arr1.every((val, i) => val === arr2[i])).

Genuinely all I’m doing is comparing arr with moveLeft(arr), yet both Ramda’s equal and my arrEq always return true regardless if they’re identical or not. If I hardcode the values of the result of arr and moveLeft(arr) and compare them then both functions behave as expected.

All values in both arrays are integers, and are always the same length.

import * as R from 'ramda'
const row = [0, 2, 0, 8]
const moveLeft = row => { ... }

const canMoveLeft = row => {
  // moveLeft(row) => [2, 8, 0, 0]
  return R.equals(row, moveLeft(row))
}

canMoveLeft(row) // => true
R.equals([0, 2, 0, 8], [2, 8, 0, 0]) // => false
// same behavior if R.equals is replaced with arrEq mentioned above

What am I missing here? Thanks in advanced.

Error: You are running `create-react-app` 5.0.0, which is behind the latest release (5.0.1)

As the title says, I cannot run create-react-app.

You are running `create-react-app` 5.0.0, which is behind the latest release (5.0.1).

We no longer support global installation of Create React App.

Please remove any global installs with one of the following commands:
- npm uninstall -g create-react-app
- yarn global remove create-react-app

The latest instructions for creating a new app can be found here:
https://create-react-app.dev/docs/getting-started/

Doing this does not change the error. npm uninstall -g create-react-app

I entered this command to try it out and got a message that the tar was out of date.
npm install -g create-react-app

npm WARN deprecated [email protected]: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
npm ERR! code EEXIST
npm ERR! path /opt/homebrew/bin/create-react-app
npm ERR! EEXIST: file already exists
npm ERR! File exists: /opt/homebrew/bin/create-react-app
npm ERR! Remove the existing file and try again, or run npm
npm ERR! with --force to overwrite files recklessly.

npm ERR! A complete log of this run can be found in:

https://www.npmjs.com/package/tar

I ran the command with this reference.

However, the tar was not updated.
I have already tried all the published solutions, but they don’t work. Can someone please help me? Please.

I tried clearing the cache but could not solve the problem.
npx clear-npx-cache

Need to install the following packages:
  clear-npx-cache
Ok to proceed? (y) y

I was able to successfully run the following command by specifying the version each time, but it is a hassle and I want to be able to run it normally.
npx create-react-app@latest my-app

Sharing combine Observables in rxjs without recalculating mapped values

Not quite sure how to formulate this question, but I’m trying to combine one event with multiple other events, in a way in which the shared event’s pipeline is only calculated once (to avoid unnecessary calculations or sever requests)

Here is an example of the problem I want to solve:

import {
  fromEvent,
  combineLatest,
  map
} from 'rxjs';
import Emitter from 'events'

const emitter = new Emitter()

const shared = fromEvent(emitter, 'shared')
const specific1 = fromEvent(emitter, '1')
const specific2 = fromEvent(emitter, '2')

const pipe = shared.pipe(
  map(() => {
    const calculatedValue = Math.random()
    // This function is called twice, instead of once
    console.log(`calculation performed: ${calculatedValue}`)
    return calculatedValue
  })
)

/**
 * @param {import('rxjs').Observable<any>} observable 
 */
const combine = (observable) => {
  combineLatest([pipe, observable]).subscribe(console.log)
}

combine(specific1)
combine(specific2)

console.log('Emitting shared event')
emitter.emit('shared')
// logs: "calculation performed: [random value]
// logs: "calculation performed: [a different random value]

console.log('Emitting event 1')
emitter.emit('1')
// uses the first random number

console.log('Emitting event 2')
emitter.emit('2')
// uses the second random number

The first and second combined observables are now using two different values, although I want them to be using the same. Is there a way I can ensure the map function is only called once, while still using rxjs functions (i.e. avoiding writing a variable with the calculated value)

Another example you can see here, using html buttons

Update the start and end index of the substring in JavaScript

I want to update the start and end index of the substring.

I have an initial text which is

This is first text and this is second text

I have indexes array of text substring which is

[
  {
    "start": 14,
    "end": 18,
    "value": "text"
  },
  {
    "start": 38,
    "end": 42,
    "value": "text"
  }
]

When i change the initial text to

This is first text and text123 this is second text

Then I want to change the start and end index of the second text substring.
I tried the below approach.

let text = "This is first text and this is second text";
let indexes = [
  {
    "start": 14,
    "end": 18,
    "value": "text"
  },
  {
    "start": 38,
    "end": 42,
    "value": "text"
  }
]
let newIndexes = [];
indexes.forEach(i=>{
  const { start, end, value } = i
  if(text.substring(start,end) === value){
    newIndexes.push(i)
  }else{
    const regexObj = new RegExp(i.value, "gmi");
    let match;
    while ((match = regexObj.exec(text)) !== null) {
       newIndexes.push({
         ...i,
         start:match.index,
         end: regexObj.lastIndex
       })
    } 
  }
})


console.log(newIndexes)

I am getting the below result

[
    {"start":14,"end":18,"value":"text"},
    {"start":14,"end":18,"value":"text"},
    {"start":23,"end":27,"value":"text"},
    {"start":46,"end":50,"value":"text"}
]

But I want the result should be

[
    {"start":14,"end":18,"value":"text"},
    {"start":46,"end":50,"value":"text"}
]

Is there a workaround for this error while working on a Backstage app ? KnexTimeoutError: Knex: Timeout acquiring a connection

So I am trying to connect an external PostgresSQL DB hosted on SG(ScaleGrid). I have configured the cluster & got a connection string with all the credential parameters.

The error occurs when trying to access this DB via a Backstage start up development configuration which generates the error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?.

Naturally, I tried a bunch of stuff after encountering this error for the first time with the closest solution/remedy being this piece of additional override for the PostgresSQL connection pool to include in the app-config.yaml file (source: https://backstage.io/docs/tutorials/switching-sqlite-postgres#override-default-postgresql-database-pool-configuration):

database:
    client: pg
    connection:
      host: ${POSTGRES_HOST}
      port: ${POSTGRES_PORT}
      user: ${POSTGRES_USER}
      password: ${POSTGRES_PASSWORD}
    knexConfig:
      pool:
        min: 3
        max: 12
        acquireTimeoutMillis: 60000
        createTimeoutMillis: 30000
        destroyTimeoutMillis: 5000
        idleTimeoutMillis: 60000
        reapIntervalMillis: 1000
        createRetryIntervalMillis: 200
        propagateCreateError: false

But unfortunately, I still encounter the same error .. Any help, thought or workaround is welcomed

filter nested array of objects using javascript

I am finding difficulty in filtering an nested array of object. Can someone please let me know where i am going wrong.

Here is the data and i want to filter out all objects which has risk P1

    {
        "title": "QA",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server down",
            },
            {
                "risk": "P3",
                "Title": "Permission issue",
            }
        ]
    }, 
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P5",
                "Title": "Console log errors fix",
            },
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

I want the result as follows

[
    {
        "title": "QA",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server down",
            }
        ]
    }, 
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

In order to achieve this, i tried this way but unable to get desired result. Can someone please let me know where i go wrong

data.forEach((element, index) => {
  return element.rows.filter( x => x.risk === 'P1' )
});

Issue with Stubbing on promised ajax call

I am writing unit test case for the promised Ajax call function which written commonly to handle all Ajax calls. When i’m trying to stub this common function. My stubbed Promise not resolving and not coming inside the then statement and not calling the success callback function given inside then statement.

function ajaxCallPromise() {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: url,
      type: 'GET,
      success: function (data) {
        resolve(data)
      },
      error: function (error) {
        reject(error)
      },
    })
  })
}

// Calling the promised Ajax function here

ajaxCallPromise()
  .then((data) => {
    console.log(data)
    doSomethingElse()
  })
  .catch((error) => {
    console.log(error)
  })

Jsunit stubbing here

it('should ajax components', function (done) {

    var newPromise = new Promise(resolve => {
        resolve(socialJson);
    });
    var resolveStub = sinon.stub(window, 'ajaxCallPromise');
    resolveStub.returns(newPromise);
    
    // Calling the promised function
    window.ajaxCallPromise();
});

After stubbing doSomethingElse callback is not calling here