Let's create a React File Manager Chapter XVII: Create Nodes List
Tags: express, typescript, mongez, javascript
Published: 2022-09-16 09:29:52

---
title: Let's create a React File Manager Chapter XVII: Create Nodes List
published: true
description: 
series: File Manager React Mongez
tags: express, typescript, mongez, javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aaxrogi0uf39gqllexjt.png
# Use a ratio of 100:42 for best results.
---

We're continuing in our list directory route.

We now listed the node files and directories, but we need to make each child as proper node.

Let's get the same `Node` type that we did in our React Project and import it.

```ts
// src/utils/node.ts
// 👇🏻 import the Node type from the client directory xD
import { Node } from "./../../../client/src/apps/front-office/file-manager/Kernel/Kernel.types";

export type { Node };

/**
 * Generate a node object to the given path,
 * the given path should be relative to the data directory
 */
export default function makeNode(path: string, children: string[]): Node {

}
```

Now we imported the same node type from our client directory, we can use it in our server.

Then we created a `makeNode` function to generate a new node object, lets do it.

```ts
// src/utils/node.ts

// 👇🏻 import the Node type from the client directory xD

import { Node } from "./../../../client/src/apps/front-office/file-manager/Kernel/Kernel.types";

import { isDirectory, size } from "@mongez/fs";
import { dataPath } from "./paths";

export type { Node };

/**
 * Generate a node object to the given path,
 * the given path should be relative to the data directory
 */
export default function makeNode(path: string, children?: string[]): Node {
  // get the full path of the node
  const fullPath = dataPath(path);

  const node: Node = {
    path,
    name: path.split("/")?.pop() || "/",
    isDirectory: isDirectory(fullPath),
    size: size(fullPath),
  };

  if (node.isDirectory && children?.length) {
    node.children = children.map((child) =>
      makeNode((path === "/" ? path : path + "/") + child)
    );
  }

  return node;
```

So the path will be the relative path to `data` directory, so if its the root then the `path` will be **/**.

The name will be the last segment of the path so we split the path by `/` and get the last segment.

The given children are the children list of the node, so we map over them and generate a new node for each child.

If there are children then we'll loop over them and generate a new node for each child.

> Don't forget the given children is list of names for the given node path, so we need to add the child name to the path.

The `isDirectory` will be the result of `isDirectory` function that we imported from `@mongez/fs` package, we need to pass the full path of the node path so we used `fullPath` to get the full path using `dataPath`.

The `size` will be the result of `size` function that we imported from `@mongez/fs` package, we need to pass the full path of the node path so we used `fullPath` to get the full path using `dataPath`.

## Calling the function

Now let's head to our `listDirectory` route and call the `makeNode` function.

```ts
import fs from "@mongez/fs";
import makeNode from "app/utils/node";
import { dataPath } from "app/utils/paths";
import { Request, Response } from "express";

/**
 *List directories
 */
export default async function listDirectory(
  request: Request,
  response: Response
) {
  // get the directory path from the request query string
  // let's set `/` as the default path
  const path = (request.query.path as string) || "/";
  const directoryPath = dataPath(path); // the full path to the directory

  if (!fs.isDirectory(directoryPath)) {
    return response.status(404).json({
      message: "Directory not found",
    });
  }

  // get the directory content
  const children = fs.list(directoryPath);

  return response.json({
    node: makeNode(path, children),
  });
}
```

Now let's run the server and see it again.

![Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4udco9yirm2tthm8kobw.png)

Walaa, It works!.

Actually we can always return children with empty array if the node is an array, because we may later add another feature to set the depth of the children, so we can return the children of the children.

```ts
// src/utils/node.ts

/**
 * Generate a node object to the given path,
 * the given path should be relative to the data directory
 */
export default function makeNode(path: string, children?: string[]): Node {
  // get the full path of the node
  const fullPath = dataPath(path);

  const node: Node = {
    path,
    name: path.split("/")?.pop() || "/",
    isDirectory: isDirectory(fullPath),
    size: size(fullPath),
  };

   // 👇🏻 we can always return children with empty array if the node is a directory
  if (node.isDirectory) {
    node.children = (children || []).map((child) =>
    // 👇🏻 we need to check if the path is the root then we will just append it to the child
    // if its not the root then we need to append `/` to the path and then append the child    
      makeNode((path === "/" ? path : path + "/") + child)
    );
  }

  return node;
}
```

Now we can try any route to check if it works properly.

- `http://localhost:3000/file-manager?path=/` will return the root directory.
- `http://localhost:3000/file-manager?path=/Application` will return the `Application` directory.

## Next Chapter

In the next chapter we'll implement this api in our React project to make it more real.

## Article Repository

You can see chapter files in [Github Repository](https://github.com/hassanzohdy/file-manager-react/tree/17-create-nodes-list)

> Don't forget the `main` branch has the latest updated code.

## Tell me where you are now

If you're following up with me this series, tell me where are you now and what you're struggling with, i'll try to help you as much as i can.

Salam.