FileReader API: Mobile Chrome is not responding

I have some JS FileReader API Script which should convert PDFs into base64 strings.
Everything works fine on Desktop Browser but in mobile Chrome and Firefox it doesn’t work.
Mobile Chrome will not respond and I have to kill the App. Mobile Firefox console says “too much recursion”.

HTML:

<input type="file" accept=".pdf" id="file" name="file" required />
<br/>
<br/>
<h2>
output:
</h2>
<div id="output"></div>

JavaScript:

function readFile(file, description, callback) {
  const fileReader = new FileReader();
  fileReader.readAsDataURL(file);
  fileReader.onload = () => {
    const fileData = fileReader.result.replace(/data:(.*)/(.*);base64,/, "");
    callback({
      name: file.name,
      description: description,
      size: file.size,
      mimetype: file.type,
      bytes: fileData
    });
  }
}

document.getElementById("file").addEventListener('change', function(event) {

    const input = event.target;
  const result = readFile(input.files[0], input.name, function(result) {
    console.log(result);
    document.getElementById("output").innerHTML = result.bytes;
  });
 
});

You can test test the whole thing here: https://jsfiddle.net/fnoq8gs3/9/

How to insert today’s date into Multiple Image URLs?

I have a same question but I have multiple image URLs: How to insert today’s date into a IMAGE URL?

I have the image URL as follows:

<img src="https://www.example.com/2023/01/08/dl/01/image.jpg" alt="image"><br>
<img src="https://www.example.com/2023/01/08/dl/02/image.jpg" alt="image"><br>
<img src="https://www.example.com/2023/01/08/dl/03/image.jpg" alt="image"><br>
<img src="https://www.example.com/2023/01/08/dl/04/image.jpg" alt="image"><br>
<img src="https://www.example.com/2023/01/08/dl/05/image.jpg" alt="image"><br>

How do I insert today’s date code on all the IMAGE URLs using javascript.

vue interceptors retry failed request and get response from component?

How I can get the response from vue axios interceptors to components where the request failed when I retry the failed request inside the interceptor?

code:

Component1.vue

axios.get('/api-1).then((response) => {
   // Do something here
});

Component2.vue (failed API request)

axios.get('/api-2).then((response) => {
   // Do something here
});

code in Interceptors.js

axios.interceptors.response.use(function (config) {
    // Do something before request is sent

    return config;
}, async function (error) {
    // Do something in Error response
    const status = error?.response?.status || 0
    const originalRequest = error.config;
    if (status === 401) { {
        try {
            setTimeout(async () => {
                const tokenData = await axios.get('/refresh-token');
                return axios(originalRequest);
            }, 2000);
        } catch (error) {
            return false;
        }
    }
    return Promise.reject(error);
});

how can I get the response from interceptors.js to Component2.vue without using vuex?

Object result convert into another object JavaScript

How to convert the following object into the following output in JavaScript? Currently I have the following object. Can you please suggest me?

[
    {
        "attrTitle": "color",
        "attrValue": "Green"
    },
    {
        "attrTitle": "size",
        "attrValue": "M"
    },
    {
        "attrTitle": "size",
        "attrValue": "L"
    },
    {
        "attrTitle": "size",
        "attrValue": "S"
    },
    {
        "attrTitle": "color",
        "attrValue": "Red"
    }
]

Output I expected into is like the following

[
    {
        "attrTitle": "color",
        "attrValue": ["Red", "Green"]
    },
    {
        "attrTitle": "size",
        "attrValue": ["S","L","M"]
    }
]

Javascript : remove an item in an array using the given start index and end index parameters

“Given array, start index and end index, remove values in that given index range,hence shortening the array.For example, removeVal([20,30,40,50,60,70],2,4) should return [20,30,70]”

I can output [20,30], meaning that my code already can remove 40,50,60 in the array. However, I think I might be incorrect on my if statement since I cannot include ’70’ on the final output. Thank you in advance.

function removeVal(arr,start,end){
//For loop
    for(let i=0; i< arr.length; i++){
       if(arr[i] >= arr[start] && arr[i] <= arr[end]){
         arr.splice(i);
       }
    }
    return arr;
}

//2,4 is the start and end index of the array example arr[2] = 30 and arr[4] = 60
y =removeVal([20,30,40,50,60,70],2,4);
console.log(y);

How to load external website into Electron and manipulate/persist its CSS correctly?

Summary of my Goal

I want to load a third party website into Electron and manipulate its CSS. I want the CSS changes I made to persist. I want to bundle the code as an app and the CSS changes to persist when the user runs the app. The website I want to embed uses google for authentication.

  • The First Approach

The first approach I tried was to change the CSS in the browser via the Google Chrome “Overrides” feature. This did not work as the changes do not persist to users when they open the app on their machines.

The second approach is documented in this question I posted:
In Electron (Forge) when nodeIntegrationInWorker: true, embedding gmail shows a blank screen

  • The Second Approach

Note – In my code below I’ve used gmail.com as the example website to load. It creates the same problem.

index.js

const { app, BrowserWindow } = require('electron');
const path = require('path');




const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    // width: 1000,
    // height: 800,
    // resizable: false,
    // frame:false,
    webPreferences: {
       preload: path.join(__dirname, 'preload.js'),
       nodeIntegrationInWorker: true,
      contextIsolation: true
    },
  });

;
mainWindow.loadURL("https://gmail.com")
mainWindow.webContents.openDevTools();



};

app.on('ready', createWindow);


app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {

  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

preload.js

function changeCSSonLoad(){

    let ele1  = document.querySelector('123-some large class list > div > div.flex.h-full.flex-1.flex-col.md\:pl-\)');
    let ele2  = document.querySelector('456-some large class list > div > div.flex.h-full.flex-1.flex-col.md\:pl-\)');
    let ele3  = document.querySelector('789-some large class list > div > div.flex.h-full.flex-1.flex-col.md\:pl-\)');

    ele2.style.display = "none";
    ele3.style.display = "none";
    ele4.style.display = "none";



    console.log("IT WERRRRKS")

}

setTimeout(function(){ changeCSSonLoad(); }, 1000);  

The code above works fine after the user is logged in. If the user is not logged in and they are prompted to do so via Google, the screen turns blank white (the connection is severed).
It is exactly what happens in this Github post:
https://github.com/electron/electron/issues/8950

The solution in the previous link is to remove nodeIntegrationInWorker: true from my code. If I do that the CSS changes no longer work.

I’ve been online reading about preload.js and from the looks of it I am not using it correctly. This post talks about the “Proper” way to use preload.js

https://stackoverflow.com/questions/57807459/how-to-use-preload-js-properly-in-electron#:~:text=The%20proper%20way%20to%20use,here%20for%20more%20explanation%20why).

In summary,

  • I want to load a third party website into Electron and manipulate its CSS. The website I want to load uses Google for authentication. I have created a version that works except when users are prompted to authenticate.
  • I am not sure if I am using preload.js the right way and by proxy I am not sure if I am going about solving this entire problem the right way in Electron.

how to save the command prompt output to an Microsoft 365 Excel or google spreadsheets (online)

hello everyone i used a .bat file get all devise information and start to data entry it manually in google spreadsheet

https://github.com/hegazytarek/Device-information

but now i want this .bat file to import this data to Microsoft 365 Excel sheet or google spreadsheet
every new run recoded in new Row in same sheet

but i don’t want just a code i want to learn how to achieve this thing but really i don’t know from where should i start or how could i achieve my target
any help please and thanks for your time

my .bat file now can extartct the data in .txt file in the same dir. like this
enter image description here

my target to save this data in Microsoft 365 Excel sheet or google spreadsheet with the same format
enter image description here

Error : When I run the serverless deploy its pop up this kind of error

Deploying to stage dev

Error:
Error: npm.cmd ls -prod -json -depth=1 failed with code 1
    at ChildProcess.<anonymous> (C:Userskavindu.chathuranganode_modulesserverless-webpacklibutils.js:91:16)
    at ChildProcess.emit (node:events:513:28)
    at ChildProcess.emit (node:domain:489:12)
    at maybeClose (node:internal/child_process:1100:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:304:5)

this is my environment

Environment: win32, node 16.19.0, framework 3.19.0 (local) 3.24.1v (global), plugin 6.2.2, SDK 4.3.2
compute-vm-aws › Credentials: Local, "default" profile
compute-vm-aws › Docs:        docs.serverless.com
compute-vm-aws › Support:     forum.serverless.com
compute-vm-aws › Bugs:        github.com/serverless/serverless/issues

only access keys is used to connect my local machine in to aws

Pass text inside a tag to another tag using forEach

I’m trying to make a figcaption to be displayed according to its associated image. It’s a photo gallery I took the code from this video.

This piece of code works as fine as is showed in the video:

document.querySelectorAll('.image-container img').forEach(image =>{
    image.onclick = () =>{
        document.querySelector('.popup-image').style.display = 'block';
        document.querySelector('.popup-image img').src = image.getAttribute('src');
    }
});

But when I try to use the code I created to pass the figcaption‘s text to the desired tag (see .finalCaption below), I got [HTML ObjectCollection] as string. This is the code that I tried and didn’t work:

document.querySelector('.finalCaption').innerHTML = image.getElementsByClassName('caption');

This is the HTML code from where the tag text should’ve come from (it’s several .images because it is a photo gallery):

<div class="image-container">
    <div class="image">
        <figure>
            <img src="image.jpg" alt="">
            <figcaption class="caption">Some figcaption text</figcaption>
        </figure>
    </div>
</div>

And this is where it should go when clicked (it should have been displayed as a popup image like in lightbox):

<div class="popup-image">
    <span>&times;</span>
    <figure>
        <img src="image.jpg" alt="">
        <figcaption class="finalCaption">Figcaption text should go here</figcaption>
    </figure>
</div>

What am I missing? How can I use each image’s figcaption to be displayed everytime it is clicked?

Thank you very much.

Why is the value inside the do while loop not updated?

I have a long list that I want to separate five by five and change the name of the value and send the first 5 to the Api. If the result is success, the next 5 will be sent.
This is what I did

let array= [{v1:0,v2:1,v3:2,v4:3},{v1:4,v2:5,v3:6,v4:7},{v1:8,v2:9,v3:10,v4:11},{v1:12,v2:13,v3:14,v4:15}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

and:

    let chunkSize = 5;
       const chunkResult = array.reduce((resultArray, item, index) => {
              const chunkIndex = Math.floor(index / chunkSize);
              if (!resultArray[chunkIndex]) {
                resultArray[chunkIndex] = []; // start a new chunk
              }
              resultArray[chunkIndex].push(item);
              return resultArray;
            }, []);
    
 ///   result chunkResult --> [[{v1:0,v2:1,v3:2,v4:3},{v1:4,v2:5,v3:6,v4:7},{v1:8,v2:9,v3:10,v4:11},{v1:12,v2:13,v3:14,v4:15},{v1:12,v2:13,v3:14,v4:15}], Array(5), Array(5), Array(5), Array(5), Array(5), Array(5)]

and:

                var j = 0;
                var check = false;
                do {
                  const element = chunkResult[j];
                  let convertArray = element.map(
                    ({
                      v1: tafzilCode,
                     v2: nationalCode,
                      v3: remain,
                      v4: credit,
                    }) => ({
                      tafzilCode,
                      nationalCode,
                      remain,
                      credit,
                    })
                  );


//result convertArray ->[{tafzilCode:0,nationalCode:1,remain:2,credit:3},{...},{...},{..},{..}]
    
    
    
                  props.service(
                    convertArray,
                    (status, result) => {
////console.log(result?.success)-->true
                      if (result?.success) {
                        check=true;
                        j++;
                      } else {
                       check=false;
                      }
                    }
                  );
             ///console.log(check)-->false 
                } while (j < chunkResult.length && check);

But what happens is that even though success is true, the check is not updated And only the first 5 will be sent.Where is my mistake?

pdfmake Insert Page Break in table rows

I am using pdfmake for generating an organizational document which includes lots of employee information of different groups. I want to insert a page break when new group starts. But here two page breaks are being added.

In the screenshot you can see page number 3 is being added which I want to get rid of.
Screenshots of Demo-Document

Code:

$(document).ready(function() {
  var demo_document = {
    pageOrientation: "landscape",
    pageMargins: [40, 80, 40, 40],
    header: function(currentPage, pageCount) {
      return [{
          text: "Company Name",
          bold: true,
          fontSize: 14,
          alignment: "center",
          margin: [0, 25, 0, 0],
        },
        {
          text: "Address: House, Road, City, Country",
          alignment: "center",
        },
      ];
    },
    footer: function(currentPage, pageCount) {
      return [{
        text: "Page " + currentPage.toString() + " of " + pageCount.toString(),
        alignment: "center",
      }, ];
    },
    content: [{
      table: {
        widths: ["auto", "*", "*", "auto", "*"],
        headerRows: 1,
        dontBreakRows: true,
        body: [
          [{
              text: "ID",
              style: "columnHeader"
            },
            {
              text: "Name",
              style: "columnHeader"
            },
            {
              text: "Designation",
              style: "columnHeader"
            },
            {
              text: "Salary",
              style: "columnHeader"
            },
            {
              text: "Remarks",
              style: "columnHeader"
            },
          ],
          [{
              text: "First Group",
              colSpan: 5,
            },
            {},
            {},
            {},
            {},
          ],
          [{
            text: "01"
          }, {
            text: "AA"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "02"
          }, {
            text: "BB"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "03"
          }, {
            text: "CC"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "04"
          }, {
            text: "DD"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "05"
          }, {
            text: "EE"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "06"
          }, {
            text: "FF"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "07"
          }, {
            text: "GG"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "08"
          }, {
            text: "HH"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "09"
          }, {
            text: "II"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "10"
          }, {
            text: "JJ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "11"
          }, {
            text: "KK"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "12"
          }, {
            text: "LL"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "13"
          }, {
            text: "MM"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "14"
          }, {
            text: "NN"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "15"
          }, {
            text: "OO"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "16"
          }, {
            text: "PP"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "17"
          }, {
            text: "QQ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "18"
          }, {
            text: "RR"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "19"
          }, {
            text: "SS"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "20"
          }, {
            text: "TT"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "21"
          }, {
            text: "UU"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "22"
          }, {
            text: "VV"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "23"
          }, {
            text: "WW"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "24"
          }, {
            text: "XX"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "25"
          }, {
            text: "YY"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "26"
          }, {
            text: "ZZ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
              text: "",
              colSpan: 5,
              pageBreak: "before",
            },
            {},
            {},
            {},
            {},
          ],
          [{
              text: "Second Group",
              colSpan: 5,
            },
            {},
            {},
            {},
            {},
          ],
          [{
            text: "27"
          }, {
            text: "AB"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "28"
          }, {
            text: "BC"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "29"
          }, {
            text: "CD"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "30"
          }, {
            text: "DE"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "31"
          }, {
            text: "EF"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "32"
          }, {
            text: "FG"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "33"
          }, {
            text: "GH"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "34"
          }, {
            text: "HI"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "35"
          }, {
            text: "IJ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "36"
          }, {
            text: "JK"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "37"
          }, {
            text: "KL"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "38"
          }, {
            text: "LM"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "39"
          }, {
            text: "MN"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "40"
          }, {
            text: "NO"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "41"
          }, {
            text: "OP"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "42"
          }, {
            text: "PQ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "43"
          }, {
            text: "QR"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "44"
          }, {
            text: "RS"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "45"
          }, {
            text: "ST"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "46"
          }, {
            text: "TU"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "47"
          }, {
            text: "UV"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "48"
          }, {
            text: "VW"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "49"
          }, {
            text: "WX"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "50"
          }, {
            text: "XY"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "51"
          }, {
            text: "YZ"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
          [{
            text: "52"
          }, {
            text: "ZA"
          }, {
            text: "Officer"
          }, {
            text: "1000"
          }, {
            text: ""
          }],
        ],
      },
      layout: {
        hLineWidth: function(i, node) {
          return i === 0 || i === node.table.body.length ? 1 : 0.5;
        },
        vLineWidth: function(i, node) {
          return i === 0 || i === node.table.widths.length ? 1 : 0.5;
        },
        hLineColor: function(i, node) {
          return "#777777";
        },
        vLineColor: function(i, node) {
          return "#777777";
        },
      },
    }, ],
    styles: {
      columnHeader: {
        bold: true,
        alignment: "center",
      },
    },
  };

  pdfMake.createPdf(demo_document).getDataUrl(function(frontSource) {
    document.getElementById("demo-document").src = frontSource;
  });
});
.container .row .col-12 .embed-responsive .embed-responsive-item {
  width: 100%;
  height: 500px;
}
<!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" />
  <title>Document</title>

  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
  <div class="container">
    <div class="row border m-1">
      <div class="col-12">
        <div class="embed-responsive embed-responsive-4by3 text-center">
          <iframe class="embed-responsive-item" src="" id="demo-document"></iframe>
        </div>
      </div>
    </div>
  </div>

  <script src="https://code.jquery.com/jquery-3.6.3.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.72/pdfmake.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.72/vfs_fonts.js"></script>
</body>

</html>

How can I remove extra page break?

Why can click not see update

I am building a d3js based javascript frontpage. Whilst restructuring some code from functional to OOP the click method stopped being able to find the update method. I get Uncaught ReferenceError: this.update is not defined. I think its something to do with scope but im quite new to js so its hard for em to figure it out, any ideas?

   class UpdateTree{

       update(source){}

       enter_new_nodes_at_the_parents_previous_position(node, source){
           var nodeEnter = node.enter().append("g")
             .attr("class", "node")
             .attr("transform", function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
             .on("click", this.click);

       click(d) {

      if (d.children) {
          d._children = d.children;
          d.children = null;
      } else {
          d.children = d._children;
          d._children = null;
      }
      this.update(d);
    }
}

how can i describe and call a function of a type of object in typescript?

well,I am learning typescript right now and getting a problem.i do not know the reason.hopeing someone can solve this
when I call the function of a object.vscode throw a error that type of {} has no call signatures.
I’ve tried describe the type of function.but I failed

console.log(b.<object>fn())
let b: { name: string; fn: {} }

b = {
  name: 'derek',
  fn: (): void => {
    console.log('i am a function')
  }
}

console.log(b.fn())