Jade mixins not getting working from external file


I have placed jade mixin code in a separate file and requiring that file in the actual jade file. But the mixins are not getting imported. It works only if the mixin code is placed in the same file.

The error is:

TypeError: /home/rishabh/Documents/my_projects/getting_MEAN/loc8r/app_server/views/location-info.jade:13
    11|         .col-xs-12.col-sm-6
    12|           p.rating
  > 13|             +outputRating(location.rating)
    14|           p= location.address
    15|           .panel.panel-primary
    16|             .panel-heading

jade_mixins.outputRating is not a function
    at eval (eval at exports.compile (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:172:8), <anonymous>:159:28)
    at eval (eval at exports.compile (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:172:8), <anonymous>:678:22)
    at res (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:173:38)
    at Object.exports.render (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:269:10)
    at Object.exports.renderFile (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:305:18)
    at View.exports.renderFile [as engine] (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/jade/lib/jade.js:290:21)
    at View.render (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/view.js:76:8)
    at Function.app.render (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/application.js:502:10)
    at ServerResponse.res.render (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/response.js:777:7)
    at Object.module.exports.locationInfo [as handle] (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/app_server/controllers/locations.js:34:9)
    at next_layer (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/route.js:103:13)
    at Route.dispatch (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/route.js:107:5)
    at /home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/index.js:195:24
    at Function.proto.process_params (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/index.js:251:12)
    at next (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/index.js:189:19)
    at next (/home/rishabh/Documents/my_projects/getting_MEAN/loc8r/node_modules/express/lib/router/index.js:166:38)

The mixin that i have used is below. I have kept int in a separate file and then requiring it in the jade file where it has to be used.

mixin outputRating(rating)
- for (var i = 1; i <= rating; i++)
span.glyphicon.glyphicon-star
- for (i = rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty

The jade layout file that is actually using that mixin is below. WHen the mixin is placed directly in the file, it works but when referenced from an external file it shows the error, above.

extends layout

include _includes/sharedHTMLfunctions

block content
  .row.page-header: .col-lg-12
      h1= pageHeader.title
  .row
    .col-xs-12.col-md-9
      .row
        .col-xs-12.col-sm-6
          p.rating
            +outputRating(location.rating)
          p= location.address
          .panel.panel-primary
            .panel-heading
              h2.panel-title Opening hours
            .panel-body
              each time in location.openingTimes
                p
                  | #{time.days} :
                  if time.closed
                    | closed
                  else
                    | #{time.opening} - #{time.closing}
          .panel.panel-primary
            .panel-heading
              h2.panel-title Facilities
            .panel-body
              each facility in location.facilities
                span.label.label-warning
                  span.glyphicon.glyphicon-ok
                  | &nbsp;#{facility}
                | &nbsp;
        .col-xs-12.col-sm-6.location-map
          .panel.panel-primary
            .panel-heading
              h2.panel-title Location map
            .panel-body
              img.img-responsive.img-rounded(src="http://maps.googleapis.com/maps/api/staticmap?center=#{location.coords.lat},#{location.coords.lng}&zoom=17&size=400x350&sensor=false&markers=#{location.coords.lat},#{location.coords.lng}&scale=2")
      .row
        .col-xs-12
          .panel.panel-primary.review-panel
            .panel-heading
              a.btn.btn-default.pull-right(href="/location/review/new") Add review
              h2.panel-title Customer reviews
            .panel-body.review-container
              each review in location.reviews
                .row
                  .review
                    .well.well-sm.review-header
                      span.rating
                        +outputRating(review.rating)
                      span.reviewAuthor #{review.author}
                      small.reviewTimestamp #{review.timestamp}
                    .col-xs-12
                      p !{(review.reviewText).replace(/\n/g, '<br/>')}
    .col-xs-12.col-md-3
      p.lead #{location.name} #{sidebar.context}
      p= sidebar.callToAction


Of course I think I'm a little bit late and you don't need help anymore, but maybe someone else will need it :)

The problem is that you wrote a mixin function in a wrong way. In jade file you shouldn't forget about indentation.

Wrong version:

mixin outputRating(rating)

-for (var i = 1; i <= rating; i++)
span.glyphicon.glyphicon-star

-for (i = rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty

Right version:

mixin outputRating(rating)

   -for (var i = 1; i <= rating; i++)
      span.glyphicon.glyphicon-star
    enter code here

   -for (i = rating; i < 5; i++)
      span.glyphicon.glyphicon-star-empty

This probably should be a comment rather then an answer however I don't have privilege to comment so hopefully no downvoat.

Is is possible that that you placed it in a different directory then the jade/pug file? Please specify the file location under what folder directory are both files placed.


I think your include is not correct, try

include ./_includes/sharedHTMLfunctions

or

include ../_includes/sharedHTMLfunctions

You can check my folder estructure and the includes, it works for me!

Folder Structure

In layouts/_boostrap.pug I have:

include ../includes/_mixins.pug
doctype html
   html(lang="es")
       head
           ...
       body
           ...

In includes/_mixins.pug I have:

//- bootstrap.jade
//- bootstrap mixins

//- Including Icon mixins
include ../components/icons
//- Including Alert mixins
include ../components/alerts
//- Including Tooltip mixins
include ../components/tooltips
//- Including Accordion mixins
include ../components/accordion