Read multiple files with Promise.all

Hi, guys. I’m working on a plugin and I’m using the following code to read the content of a list of files:

const fileContents: string[] = await Promise.all(
   listFiles.map((file) => this.app.vault.cachedRead(file))
);

My problem is that this code returns an array with the content of the files, but I can’t figure out how to program a script that returns the contents of the files along with the name of the file the content is associated with. I can’t figure out how to do that with Promises. If anyone has any idea, I highly appreciate it.

Thanks
JD

const fileContents: [path:string, content:string][] = await Promise.all(
   listFiles.map(async (file) => [file.path, await this.app.vault.cachedRead(file)])
);
for (const [path, content] of fileContents) {...}

Hi, aidenix. I tried to return a tuple before, but I always get the following error (this is the error I get with your code):

main.ts:73:9 - error TS2322: Type 'string[][]' is not assignable to type '[path: string, content: string][]'.
  Type 'string[]' is not assignable to type '[path: string, content: string]'.
    Target requires 2 element(s) but source may have fewer.

73   const fileContents: [path:string, content:string][] = await Promise.all(

Maybe I need to create a loop with Promises for each file? But I never worked with Promises before so I’m not sure how to do that.

Thanks in advance
JD

I think I’ve got it. I’ve created this loop and it works. Let me know if you see any potential bugs. Thanks again for your time.

		let listContents: [string, string][] = [];
		await listFiles.forEach(async (file) => {
			let content = await this.app.vault.cachedRead(file);
			listContents.push([file.name, content]);
		});

append as const should work, I didn’t notice the type issue because I wrote the code without IDE at that moment :joy:

const fileContents: [path:string, content:string][] = await Promise.all(
   listFiles.map(async (file) => [file.path, await this.app.vault.cachedRead(file)] as const)
);
for (const [path, content] of fileContents) {...}

Hi, aidenix. Unfortunately, I’m still getting an error. Now it says that the const values can’t be assigned to the mutable value (I removed the labels in the tuple but I get the same error).

main.ts:100:9 - error TS2322: Type '(readonly [string, string])[]' is not assignable to type '[string, string][]'.
  The type 'readonly [string, string]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'.

100   const fileContents: [string, string][] = await Promise.all(

The loop I showed you before works, I’m just not sure if there is any possible bug in there.

Thanks
JD

you can do that loop of course, it’s just that the map will be more straightforward, the following code should stop the complaint from typescript

const fileContents = await Promise.all(
  listFiles.map(
    async (file) => [file.path, await app.vault.cachedRead(file)] as const,
  ),
);