JavaScript – beginner’s excersise [closed]

I have a problem with the task. I would like the easiest way to get the result, which is a tree with all the elements.
The object looks like this:

const bookPages = [
    {
        name: '1',
        content: [
            {
                name: '1.1',
                content: [
                    {
                        name: '1.1.1',
                        content: []
                    }
                ]
            },
            {
                name: '1.2',
                content: []
            }
        ]
    },
    {
        name: '2',
        content: [
            {
                name: '2.1',
                content: []
            }
        ]
    }
]

console.log(bookPages);

After typing this to the console I would like to get a similar result:

// - 1
// -- 1.1
// --- 1.1.1
// -- 1.2
// -2
// --2.1

WHAT would be the easiest way to do it? Thanks

Styled Components with bracket doesn’t work properly in Next.js

Styled Components with bracket doesn’t work properly in Next.js
I’m using typescript, styled-components with Next.js

package.json

    "dependencies": {
             "@reduxjs/toolkit": "^1.6.2",
             "babel-plugin-styled-components": "^2.0.2",
             "next": "12.0.4",
             "react": "17.0.2",
             "react-dom": "17.0.2",
             "react-inlinesvg": "^2.3.0",
             "react-redux": "^7.2.6",
             "redux": "^4.1.2",
             "redux-saga": "^1.1.3",
             "styled-components": "^5.3.3"
    },
    "devDependencies": {
             "@types/node": "^16.11.10",
             "@types/react": "^17.0.37",
             "@types/styled-components": "^5.1.15",
             "eslint": "7.32.0",
             "eslint-config-next": "12.0.4",
             "typescript": "^4.5.2"
    }

.babelrc

    {
    "presets": ["next/babel"],
    "plugins": [
       [
         "babel-plugin-styled-components",
         {
            "ssr": true, 
            "displayName": true, 
            "preprocess": false
         }
       ]
    ]
    }

_document.tsx

import React from "react";
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";
class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

but in a certain situation, like using Styled Components with bracket, and the components in the bracket were imported, styled-components cannot apply any of it.

(it can render the imported component, but cannot apply any additional styles)

RegisterForm.tsx

    import React, { useState } from 'react';
    import styled from 'styled-components';
    import RoundButton from '../../components/common/RoundButton';

    const RoundButtonWithMarginTop = styled(RoundButton)`
        margin-top: 3.75rem;
    `;

    const RegisterForm = () => {
         ...
         <RoundButtonWithMarginTop>Next</RoundButtonWithMarginTop>
         ...
    }

components/common/index.tsx

    export * from './Header';
    export * from './Responsive';
    export * from './RoundButton';

components/common/RoundButton.tsx

import React from 'react';
import styled from 'styled-components';
import palette from '../../lib/styles/palette';

const RoundButtonBlock = styled.button`
    width: 100%;
    background-color: ${palette.Gray[1]};
    border-radius: 30px;
    border: none;
    font-size: 1.1em;
    font-weight: 700;
    height: 3rem;

    cursor: pointer;

    &:hover {
        background-color: ${palette.Gray[0]};
    }
`;

const RoundButton = ({ children }) => {
    return (
        <RoundButtonBlock>
            {children}
        </RoundButtonBlock>
    );
};

export default RoundButton;

how button appears on the page

How can I solve this problem?
Please give me the solution.

Filtering array of objects with nestead array loop

I am trying to filter an array, based on some nested object.
the final value would be the main object.

this is the data I have.

JSonData =  [
        {
            "ID": 1,
            "Name": "0ABCDDDD",
            "Business Profile Owner": "owner ",
            "Folder": "out-of-the-box strategize methodologies",
            "Profile Type": "Greenholt",
            "status": "low"
            "Risk": [
              {
                "ID": 1.1,
                "Name": "Tiaxxxxxnna",
                "Risk Owner": "Lindgren",
                "Risk Taxonomy": "Lindgren",
                "status": "high"
                "Control": [
                  {
                    "ID": 1.2,
                    "Name": "rrrrrrrrrr",
                    "Control Owner": "333333",
                    "Control Hierarchy": "North Laurineshire",
                    "Control Type 3": "Jerde Spring",
                    "status": "high"
                  },
                  {
                    "ID": 1.21,
                      "Name": "cccccccActive",
                    "Control Owner": "333333",
                    "Control Hierarchy": "North Laurineshire",
                    "Control Type 3": "Jerde Spring",
                    "status": "low"
                  }
                ]
              },
              {
                ID: 1.11,
                Name: "Tiaxxxxxnna",
                "Risk Owner": "rRrrrrrrrrrrr",
                "Risk Taxonomy": "rrrrrrrrrrrr",
                "status": "low"
              }
            ]
    
    }, {
            "ID": 2,
            "Name": "dddd0ABCDDDD",
            "Business Profile Owner": "ddddd ",
            "Folder": "strategize methodologies",
            "Profile Type": "ssd",
            "status": "high"
            "Risk": [
              {
                "ID": 2.1,
                "Name": "deeeeeec",
                "Risk Owner": "Lindgren",
                "Risk Taxonomy": "Lindgren",
                "status": "high"
                "Control": [
                  {
                    "ID": 2.2,
                   "Name": "3Active",
                    "Control Owner": "333333",
                    "Control Hierarchy": "North Laurineshire",
                    "Control Type 3": "Jerde Spring",
                    "status": "high"
                  },
                  {
                    "ID": 2.21,
                    "Name": "55555Active",
                    "Control Owner": "333333",
                    "Control Hierarchy": "North Laurineshire",
                    "Control Type 3": "Jerde Spring",
                    "status": "low"
                  }
                ]
              },
              {
                ID: 2.11,
                Name: "33333333",
                "Risk Owner": "eeeeeeee",
                "Risk Taxonomy": "wwwwwwwww",
                "status": "high"
              }
            ]
    
    }, {
            "ID": 3,
            "Name": "WWWW",
            "Business Profile Owner": "Business Profile",
            "Folder": "strategize",
            "Profile Type": "cccccc",
            "status": "high"
            "Risk": [
              {
                "ID": 3.1,
                "Name": "ruchas",
                "Risk Owner": "boss",
                "Risk Taxonomy": "8989889",
                "status": "high"
                "Control": [
                  {
                    "ID": 3.2,
                     "Name": "Active",
                    "Control Owner": "eeeeee",
                    "Control Hierarchy": "North",
                    "Control Type 3": "Jerde",
                    "status": "low"
                  },
                  {
                    "ID": 3.21,
                    "Name": "Active1",
                    "Control Owner": "wwwwww",
                    "Control Hierarchy": "Laurineshire",
                    "Control Type 3": "Spring",
                    "status": "high"
                  }
                ]
              },
              {
                ID: 3.11,
                Name: "EEEE",
                "Risk Owner": "eeeeeeee",
                "Risk Taxonomy": "wwwwwwwww",
                "status": "low"
              }
            ]
        }
    ];

The multiple values which are selected from multi-select are

[{name: 'Business Profile', type: 'bp'}
{name: 'Low', type: 'risk'}
{name: 'Active', type: 'control'}]

here ‘bp’ is the main object (ID’s which are 1,2,3).
risk and control are nested objects/ Array.

it should return the following object since it matches all records.
(selected records should work with && operations)

 {
        "ID": 3,
        "Name": "WWWW",
        "Business Profile Owner": "Business Profile",
        "Folder": "strategize",
        "Profile Type": "cccccc",
        "status": "high"
        "Risk": [
          {
            "ID": 3.1,
            "Name": "ruchas",
            "Risk Owner": "boss",
            "Risk Taxonomy": "8989889",
            "status": "low"
            "Control": [
              {
                "ID": 3.2,
                 "Name": "Active",
                "Control Owner": "eeeeee",
                "Control Hierarchy": "North",
                "Control Type 3": "Jerde",
                "status": "low"
              }
            ]
          },
          {
            ID: 3.11,
            Name: "EEEE",
            "Risk Owner": "eeeeeeee",
            "Risk Taxonomy": "wwwwwwwww",
            "status": "low"
          }
       ]
}

Knex multiple primary key in a identify relationship where id is an auto increment column

I tried to use every single logic in my mind to resolve this problem, but this is the only solution that it worked.

knex.schema.createTable('documents', (table) => {
      table.integer('id').unsigned().notNullable().unique()
      table.string('path')
      table.enum('type', ['CPF', 'RG'])
      table.integer('user_id').unsigned().notNullable()
      table.foreign('user_id').references('id').inTable('users')
      table.primary(['id', 'user_id'])

      table.timestamps(true, true)
    })
    knex.schema.alterTable(this.tableName, (table) => {
      table.increments('id', { primaryKey: false }).alter()
    })
}

TypeScript – Return function value from the callback function

I am using the Error Handling method using the Result type, which I have posted in this question.

Using the Result type, I could easily build a chain of functions like this

Result.combine(result1, result2)
.onFailure(err => doSomethingOnFailure())
.onSuccess(val => doSomethingOnSuccess())

This flow looks good for me, but I have a problem.

function func(a, b) {
// Some code above
const result = Result.comine(aResult, bResult).onFailure(err => {
// I want to return fail result to the func here but do not know how
})

// So I have to do a simple if check
if (result.failure) {
// Return fail result here
}
}

I want to return the fail result to the parent function inside the onFailure function.

Could I somehow achieve this?

HTML: Scroll line by line

I have an unordered list with a variable number of list items. The <ul> is of fixed height (actually the height of a single line of text) and set to overflow-y: scroll.

When I scroll the mouse-wheel, a certain vertical distance is traversed. I would like to have it exatly scroll line by line, to ensure that a <li> is always properly centered in the visible part of the <ul>.

Wrong behaviour:
enter image description here

:root {
  --default-line-height: 24px;
}

.myUl {
  background-color: lightblue;
  height: var(--default-line-height);
  list-style-type: none;
  overflow-y: scroll;
  outline: 1px solid black;
}

.myLi {
  font-size: var(--default-line-height);
}
<ul class="myUl">
  <li class="myLi">Lorem ipsum dolor sit amet</li>
  <li class="myLi">Aenean commodo ligula eget dolor.</li>
  <li class="myLi">Cum sociis natoque penatibus</li>
  <li class="myLi">Donec quam felis, ultricies nec</li>
  <li class="myLi">Nulla consequat massa quis enim.</li>
  <li class="myLi">Donec pede justo, fringilla vel</li>
  <li class="myLi">In enim justo, rhoncus ut</li>
</ul>

<p>Please scroll the blue area.</p>

I played with scroll-snap but to no real success. I “feels” awkward.
It seemed reasonable to be able to scroll line by line under certain conditions. But after spending some hours on the subject, I’m not sure anymore :-/

Thanks in advance
Christian

How to solve Objects are not valid as a React child (found: object with keys {….?

Im trying to map my state , but it allways returns me this error, someone knows how to solve it ?

 const FormScreen = async({route}) => { 
      const [userForm, setuserForm] = useState([]);
      const mounted = useRef(true);
    
      useEffect(async() => {
        let mounted = true; 
        if (mounted && userForm.length > 0 ){
          console.log(userForm,'campos:',userForm.fields);
          return;
        }
        else {
          setuserForm(await JSON.parse(route.params.paramKey));
        }   
        return () => (mounted = false);
    }, [userForm]);
           
      return (
        <SafeAreaView style={{flex: 1}}>
          <View style={styles.container}>
            <Text style={styles.textStyle}>
              COLLECTION :
            </Text>
    
          {
            userForm.length > 0 ? (
              userForm.map(async(item) => (
          <Text keys={await item.fields.toString()}>testtt</Text>        
          )) 
          ): <Text> Loading ...</Text>}
           
          </View>
        </SafeAreaView>
      );
    };

what I’m trying to do is render all my fields and then handle the following types.

Merging two array of objects only when array element contains error

So I have two arrays with objects. And also an array indicating where the replacement should take place(It spots if object contains error)

         const oldData = [
    {
        "index": "01",
        "skuId": "Sarbb-033",
        "name": "Sasko Black",
        "barcode": "843331510012",
        "description": "Nice black bread",
        "brand": "ERROR: No brand matching: Sasko",
        "productLine": "ERROR: No product line matching: line",
        "inputType": "Weight",
        "uom": "ERROR: Invalid UoM type, valid values are: kg,g,mg,kl,l,ml,m,cm,mm",
        "value": "700",
        "capacity": "1",
        "image": ""
    },
    {
        "index": "02",
        "skuId": "ERROR: Empty sku_id is not allowed",
        "name": "Sasko Black1",
        "barcode": "ERROR: Empty barcode is not allowed",
        "description": "Nice black bread",
        "brand": "ERROR: No brand matching: Future Life",
        "productLine": "ERROR: No product line matching: line",
        "inputType": "Weight",
        "uom": "kg",
        "value": "701",
        "capacity": "2",
        "image": ""
    },
    {
        "index": "03",
        "skuId": "Sarbb-099",
        "name": "Sasko Black100",
        "barcode": "843332555614",
        "description": "Nice black bread",
        "brand": "fwfwf",
        "productLine": "naam",
        "inputType": "weight",
        "uom": "g",
        "value": "702",
        "capacity": "3",
        "image": ""
    },
    {
        "index": "04",
        "skuId": "Sarbb-100",
        "name": "Sasko Black101",
        "barcode": "ERROR: Empty barcode is not allowed",
        "description": "ERROR: Invalid description: [] it should not be blank.",
        "brand": "fwfwf",
        "productLine": "fwfwf",
        "inputType": "Weight",
        "uom": "g",
        "value": "703",
        "capacity": "4",
        "image": ""
    },
    {
        "index": "05",
        "skuId": "Sarbb-101",
        "name": "Sasko Black102",
        "barcode": "843332555616",
        "description": "Nice black bread",
        "brand": "fwfwf",
        "productLine": "naam",
        "inputType": "weight",
        "uom": "g",
        "value": "704",
        "capacity": "5",
        "image": ""
    }
]


    const newData = [
    {
        "index": "01",
        "skuId": "Sarbb-033",
        "name": "Sasko Black",
        "barcode": "843331510012",
        "description": "Nice black bread",
        "brand": "fwfwf",
        "productLine": "fwfwf",
        "inputType": "Weight",
        "uom": "g",
        "value": "700",
        "capacity": "1",
        "image": ""
    },
    {
        "index": "02",
        "skuId": "sarb",
        "name": "Sasko Black1",
        "barcode": "124125125",
        "description": "Nice black bread",
        "brand": "fwfwf",
        "productLine": "fwfwf",
        "inputType": "Weight",
        "uom": "kg",
        "value": "701",
        "capacity": "2",
        "image": ""
    },
    {
        "index": "03",
        "skuId": "Sarbb-100",
        "name": "Sasko Black101",
        "barcode": "214214214",
        "description": "Desc",
        "brand": "fwfwf",
        "productLine": "fwfwf",
        "inputType": "Weight",
        "uom": "g",
        "value": "703",
        "capacity": "4",
        "image": ""
    }
]

    const errorRows = [0,1,3]


      const myTerribleAttempt = oldTableData.map((oldData, rowIndex) => {
  return errorRows.map(index => {
    if(rowIndex === index){
     newTableData.map(newData => {
oldData = newData
     })
    }
  })
 })

I have tried multiple maps and just can’t seem to get the right result. The new data objects should replace old data objects at the object containing the error. Please give me some assistance.

how to form an array of arrays with data

I need to create an array of arrays like this:

var serviceCoors = [
        [50, 40],
        [50, 50],
        [50, 60],
    ];

from elements with datas:

<div data-latitude="10" data-longitude="20" class="service-points__map"></div>
<div data-latitude="20" data-longitude="10" class="service-points__map"></div>

I`m trying this:

var test = [];
$('.service-points__map').each(function(){
        var test2 = $(this).contents();
        var items = [];
        $.each(test2, function(i, val) {
            items.push(val.data);
        });
        test.push(items);
    });

But it doesn`t work. I have 2 arrays, but they are empty.

React, trying to return props from json

I am just trying to experiment with an app, and in my html I am trying to return the props of userData which in my console logs things such as lineStatus etc, however I seem to be returning nothing.

my code is as follows:

import React, { useState, useEffect } from 'react'
import axios from "axios";

const tflData = "https://api.tfl.gov.uk/line/mode/tube/status";

axios.request(tflData).then(function (response) {
    console.log(response.data);
}).catch(function (error) {
    console.error(error);
});

function Lines() {
    
    const [userData, setUserData] = useState({});
    const tflUserWithFetch = async () => {
        const response = await fetch(tflData);
        const jsonData = await response.json();
        setUserData(jsonData);
      };

  useEffect(() => {
    tflUserWithFetch();
  }, []);
  
  return (
    <div className="App">
      <header className="App-header">
        <h2>Line Data</h2>
      </header>
      <div className="user-container">
        <h5 className="info-item">Tube station: {userData.name}</h5>
        <h5 className="info-item">Status: {userData.lineStatuses}</h5>
     
      </div>
    </div>
  );
}

export default Lines

Basically I am trying to return the values or content values but I am missing something.

What am I missing in JavaScript?

I am just started to learn JS on Freecode and doing that task Use Recursion to Create a Range of Numbers).
The function should return an array of integers which begins with a number represented by the startNum parameter and ends with a number represented by the endNum parameter. The starting number will always be less than or equal to the ending number. Your function must use recursion by calling itself and not use loops of any kind. It should also work for cases where both startNum and endNum are the same.

My solution is on below

let myVal = [];
function rangeOfNumbers(startNum, endNum) {
  if (startNum <= endNum) {
    myVal.push(startNum);
    startNum++;
    rangeOfNumbers(startNum, endNum);
  }

  return myVal;
}

rangeOfNumbers(2, 5);

Normally it should work well but I do not know why it is not acceptable.

Test functions cannot both take a ‘done’ callback and return something. Either use a ‘done’ callback, or return a promise

I’m trying to exit the process after the unit jest testing is finished,
at the same time, I’m setting a token value from the first test to authorize all the other tests
all tests passed except the login in one
and still, the jest process is still running on the terminal.
that’s the first test where I set the token after the test

 test("should respond with a 200 status code", async (done) => {
  response = await request(app)
    .post("/login")
    .send({
      email: "[email protected]",
      password: "testtest",
    })
    .expect(200);
  token = response.header.token;

  done();
});

The goal is to quit the process after the async process on jest

How do I check whether an element is already bound to an event?

Goal

Avoid unnecessary event bindings.

Sample code

Comment box with a reply button for each individual comment

const btns = document.getElementsByClassName('reply-btn');

for (let i = 0; i < btns.length; i++) {    
  btns[i].addEventListener('click', showCommentContentAsPreview);
}


function showCommentContentAsPreview(e) {
  console.log('showCommentContentAsPreview()');
  
  // CHECK IF THIS BUTTON ALREADY BINDED !!!
  const previewDiv = document.getElementById('preview');
  const commentId = e.target.getAttribute('data-comment-id')
  const commentDiv = document.getElementById('comment-' + commentId);
  const commentText = commentDiv.querySelector('p').innerText
  const closeReplyBtn = previewDiv.querySelector('button');
  const previewContent  = previewDiv.querySelector('.preview-content');
  
  // set to preview
  previewContent.innerText = commentText;
  
  // show reply close button  
  closeReplyBtn.classList.remove('hidden');
  
  // bind EventListener to "reply close button"
  closeReplyBtn.addEventListener('click', closeReply)
  
  function closeReply() {
    console.log('bind to btn');
    previewContent.innerText = '';
    this.removeEventListener('click', closeReply);
    closeReplyBtn.classList.add('hidden');
  }
}
.hidden {
  display: none;
}

.comment {
  border-bottom: 1px solid #000;
  padding: 5px;
}


.preview {
  background-color: #ccc;
  padding: 20px;
  margin-top: 20px;
}
<div>
  <!-- comment list -->
  <div id="comment-1" class="comment">
    <p>Comment Content 1</p>
    <button class="reply-btn" data-comment-id="1">reply</button>
  </div>
  
  <div id="comment-2"  class="comment">
    <p>Comment Content 2</p>
    <button  class="reply-btn" data-comment-id="2">reply</button>
  </div>  
</div>

<!-- output -->
<div>
  <div id="preview" class="preview">
    <div class="preview-content"></div>
    <button class="hidden">Close Preview</button>
  </div>
</div>

Simulate problem

When you try the example, the following two scenarios occur:

  1. Click reply once and then click “close preview”

  2. Click on reply several times and then on “close preview”.

Question

How can I avoid multiple bindings to the same button? I am already thinking about singleton.

Problem with updating object property in array of objects in React

I’m making an ecommrece project, in search bar I’m displaying checkboxes with categories from the API, all of those have value active == true by default. This is how I’m mapping them:

{categories.map((category) => {
       return (
              <>
             <input type="checkbox" onClick={() => handleCheckbox(category)} 
             defaultChecked={category.active} key={category.name} />
             <label style={{marginLeft:"5px"}} htmlFor={category.name}>{category.name}</label><br/>
             </> 
)
})}

Then I run this function to change category.active property from true to false, when the exact checkbox is clicked, then I want to update this object using useState

const handleCheckbox = (category) => {
    let tempCategory = category
    if (tempCategory.active == true) {
        tempCategory.active = false;
    } else {
        tempCategory.active = true;
    }
    setCategories({...categories, [tempCategory.id]: tempCategory})
    console.log(category.active)
}

Unfortunetly when I click on the checkbox I’m getting an error from React:

TypeError: categories.map is not a function

And it points to categories.map, I have no idea how to fix it. All I want is to update specific object in the categories array.