0

I am developing a node.js application. I loaded a JSON file as app.locals.parameter in app.js. then I am trying to use it in my index.hbs.

Assume:

app.locals.componentData = require('./myfile.json');

when I used the parameter inside my HTML part as below it is functioning properly.

 {{#each componentData.categories}}
        <li id="{{this.categoryName}}" name="{{this.categoryName}}" class="btn btn-primary btn-sm" style="position: relative; z-index: 10; margin-bottom:3px" draggable="true" role="option" aria-grabbed="false"><div><img src="images/plugin.png" alt="{{this.categoryDescription}}"/>{{this.categoryName}}</div></li>
 {{/each}}

but when I am trying to use the parameter in my javascript function it cannot recognize it.

function InitComponents() {
         for( var i = 0; i < componentData.categories.length; i++ ){
             alert("in loop!"+i+"-"+componentData.categories[i].categoryName);
              if(componentData.categories[i].categoryName.match(itemId)){
              alert("here:"+componentData.categories[i].parameters.length);
          createParameterList(newID,componentData.categories[i].parameters);
                        }

            }

    }

my JSON format is as below:

{
    "categoryName": "xyz",
    "categories": [
      {
        "categoryName": "ABC", 
        "parameters": [
          {
            "ParameterID": "ID",
            "ParameterName": "ID",
            "ParameterDefultValue": "",
            "ParameterValue": "",
            "ParameterDescription": "ID Description"
          }]
}]
}

may I know why system cannot understand componentData.categories.length in my script part?

Amir
  • 1,919
  • 8
  • 53
  • 105

1 Answers1

1

The problem here is that InitComponents function doesn't know anything about app.locals. app.locals variable is recognized inside templates. In order to make your code work you need to pass app.locals.componentData as a parameter to InitComponents function:

function InitComponents(componentData) {
     for( var i = 0; i < componentData.categories.length; i++ ){
         alert("in loop!"+i+"-"+componentData.categories[i].categoryName);
          if(componentData.categories[i].categoryName.match(itemId)){
            alert("here:"+componentData.categories[i].parameters.length);
            createParameterList(newID,componentData.categories[i].parameters);
          }
     }
}

Now you can call this function like this

InitComponents(app.locals.componentData);

and InitComponents will now actually know what componentData is. If you use this function inside a middleware you can access app via req.app:

myMiddlewareFunction((req, res, next) => {
    const app = req.app;
    initComponents(app.locals.componentData);
    // some other logic
})
Volodymyr
  • 1,360
  • 1
  • 7
  • 12
  • @volodymry: Thanks for your answer. I added changes as you said, but now in my button which called Initial component I received this error: "Uncaught ReferenceError: app is not defined." Also, can you explain the last part of your answer, I didnt get it. where I should add it? – Amir Oct 15 '18 at 19:56
  • 1
    @Amir can you please share the code of the function inside which you call `InitComponents` function? – Volodymyr Oct 15 '18 at 20:03
  • @Volodymry: I call it like this: [previously] and now => – Amir Oct 15 '18 at 20:07
  • I think, I misunderstood your question. I thought you are trying to use `componentData` inside JS on NodeJS side. But as far as I got it now you are trying to use `componentData` inside a frontend script. If so you need to fetch this JSON file from your server and to assign it to a variable inside your script. Or you can insert a ` – Volodymyr Oct 15 '18 at 20:17
  • can you modify your answer based on your new understanding. because I am new to NodeJS. As I mentioned above I loaded the JSON in app.locals.componentData in app.js; I can use componentData successfully in my HTML part but in script part I dont know how to use it. :( – Amir Oct 15 '18 at 20:22
  • @Amir is the HTML you are talking about generated by NodeJS from index.hbs? – Volodymyr Oct 15 '18 at 20:26
  • I tried to load my json file inside – Amir Oct 15 '18 at 20:28
  • @Amir if you want to download your JSON you need to use [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) - `const componentData = fetch('public.path.to.your.json').then(response => response.json());`. Also you will need to make this JSON served by your NodeJS application ([how to serve static files in expressjs](http://expressjs.com/en/starter/static-files.html)). – Volodymyr Oct 15 '18 at 20:35
  • If you want to include your json inside ` and you should be able to use `window.componentData` in your browser script – Volodymyr Oct 15 '18 at 20:38
  • also this answer can help you - https://stackoverflow.com/questions/40386257/add-scripts-in-express-handlebars-from-view – Volodymyr Oct 15 '18 at 20:40
  • when I used I am receiving this error: Uncaght SyntaxError: Unexpected identifier The output is also is like this: any Idea what is going on? – Amir Oct 15 '18 at 20:49
  • this answer will help you with this issue - https://stackoverflow.com/questions/10232574/handlebars-js-parse-object-instead-of-object-object . You will need to use `JSON.parse` in you browser script to covert JSON to a plain object. – Volodymyr Oct 15 '18 at 21:03
  • however I would like to suggest you to go with `fetch` approach because it is less hacky – Volodymyr Oct 15 '18 at 21:06