0

Is it possible to bind a whole directory of static files to an angular 4 application? The intention behind this is to get the content of this directory dynamically to see what files are inside the directory.

I know it´s possible to bind a directory to the application using

"assets": [
    "favicon.ico",
    "assets",
    {
      "glob": "**/*.svg",
      "input": "../node_modules/@myModule/assets/images",
      "output": "./assets/images"
    }
  ]

With the above approach, you can only address the files by calling them explicit e.g. HOST:PORT/assets/images/myImage.svg

So the question is:
Is it possible to bind an directory, so I´m able to call HOST:PORT/assets/images and get all containing files dynamically?

If not: Is there another way to get all files dynamically from my static directory in my Angular app?

6
  • 1
    Not clientside-only. Commented Feb 19, 2018 at 12:42
  • did you just try to remove the "glob": "*/.svg", part or changing it to "glob": "*/.*" ? Commented Feb 19, 2018 at 12:43
  • @PierreMallet If I try this approach, neither the direct call nor the dynamic call will work. Commented Feb 19, 2018 at 12:49
  • @Zlatko Not even using JS? Commented Feb 19, 2018 at 13:03
  • Well, not client-side JS. You basically want a directory listing. JavaScript (the one on the client) can't even access local files (on the user's computer), let alone remote ones, on the server. But you may have other options, depending on what are you trying to do. What are you trying to do? Commented Feb 19, 2018 at 13:28

1 Answer 1

1

The short answer: no.

The longer answer, not right out of the box. The icons (as mentioned in your comments) are accessible, but not listable. So you can create a list of icons on build time, something like this.

Add an enumerator script in your tools or similar directory. E.g.

const fs = require('fs');
const readdirSync = fs.readdirSync;
const writeFileSync = fs.writeFileSync;
const files = readdirSync('src/assets/svg');
const jsonObj = { files };
writeFileSync('src/app/svg-files.json', JSON.stringify(jsonObj, null, 2));

Run that script in your package.json. E.g.

"scripts": {
  ...
  "listSvgs": "node tools/list-svgs"
}

Run that script in your build pipeline in package.json:

"scripts": {
  ...
  - "build": "ng build -p",
  + "build": "npm run listSvgs && ng build -p"
  ...
}

(You'll know, I guess, which line goes out and which comes in its place.)

Generate the files first time manually, so you don't forget (npm run listSvgs).

Add a service to fetch the files in your Angular code:

@Injectable
export class SVGListingService {
    constructor(private httpClient: HttpClient) {}
    getSVGs() {
        return this.http.get('svg-files.json');
    }
}

You should be able to use it, remember to rerun it when you add svgs. And adjust paths.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for this nice workaround! Can you please tell me what type of file you are using for the enumeration script in the beginning?
Just a regular JavaScript (Node.js) script. In fact, you have to name it and match with that second step, e.g. if you name it 'list-svgs.js', then cool, if you rename it, update your scripts path.
When putting the code inside an list-svg.js file and running npm run listSvgs, i get the following error (function (exports, require, module, __filename, __dirname) { const { readdirSync, writeFileSync } from 'fs'; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Missing initializer in destructuring declaration
Oh, you seem to be putting this through webpack or something? It's a simple node script, not placed together with your sources. Put it outside of your other files. What do you get when you run it directly? node list-svgs.js?
@JohnDizzle I updated the script. If it doesn't work again, can you simply open Node REPL (type "node" on command line") and paste the contents there?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.