Ionic2 You may need an appropriate loader to handle this file type

I’m suddenly getting a build error of

./app/app.js
Module parse failed: /Users/richardshergold/Documents/Ionic Projects/PortalToday/node_modules/awesome-typescript-loader/dist.babel/index.js?{“doTypeCheck”:false,“useWebpackText”:true}!/Users/richardshergold/Documents/Ionic Projects/PortalToday/app/app.js Line 117: Illegal return statement
You may need an appropriate loader to handle this file type.
| findMenuItemByTitle(title);
| {
| return this.pages.find(function (menuItem) {
| return menuItem.title === title;
| });
@ multi main (CLI v2.0.0-beta.17)

I’ve building under alpha54 and have matched up all my project config files with the Conference app.

Does anyone know what might be causing this? I removed all the node modules and then did npm install to re-install everything but it hasn’t helped. I’m not using Typescript, just js files.

Most likely you updated the webpack.config.js from the conference app with the config options for typescript and that broke it for you, post your webpack config.

Hi. Here it is:

var path = require('path');

module.exports = {
  entry: [
    path.normalize('es6-shim/es6-shim.min'),
    'reflect-metadata',
    'web-animations.min',
    path.normalize('zone.js/dist/zone-microtask'),
    path.resolve('app/app')
  ],
  output: {
    path: path.resolve('www/build/js'),
    filename: 'app.bundle.js',
    pathinfo: false // show module paths in the bundle, handy for debugging
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'awesome-typescript',
        query: {
          doTypeCheck: false,
          useWebpackText: true
        },
        include: path.resolve('app'),
        exclude: /node_modules/
      },
      {
        test: /\.js$/,
        include: path.resolve('node_modules/angular2'),
        loader: 'strip-sourcemap'
      }
    ],
    noParse: [
      /es6-shim/,
      /reflect-metadata/,
      /web-animations/,
      /zone\.js(\/|\\)dist(\/|\\)zone-microtask/
    ]
  },
  resolve: {
    alias: {
      'angular2': path.resolve('node_modules/angular2'),
      'ionic': 'ionic-framework',
      'web-animations.min': path.normalize('ionic-framework/js/web-animations.min')
    },
    extensions: ['', '.js']
  }
};

If you see the same file in a new project with js, 'doTypeCheck' key goes between quotes, and useWebPack doesn’t go there.

Also you only need the ionic alias and the web-animations.min one.

Thanks, but that didn’t make any difference unfortunately.

Try this inside your project root to wipe out ionic and cordova and reinstall:

npm uninstall -g ionic && npm uninstall -g cordova && rm -rf node_modules && npm cache clear && npm cache clean && npm i -g cordova ionic@beta && npm i

This will last for a while, grab a snack meanwhile.

Thanks - I’ll give it a go and report back :slight_smile:

Can you paste the code in app.js around this line? Include the code before/after this line, please.

Nice noticing that, have to learn how to read debug logs :stuck_out_tongue:

Well, the weird thing is I don’t have a line 117. I added the same function you have in your Conference app at the very end of my class (the last line of this is line 101).

// find a menu option
findMenuItemByTitle(title) {
  return this.pages.find((menuItem) => {
    return menuItem.title === title
  })
}

If I comment this out though, the project build then falls over on another function in another file (again complaining about the return type).

I tried the wipe out line and I still get the same error.

Aside from wiping out the install, can you put your app.js in pastebin and put it here so we can check it?

my app.js is:

// framework stuff
import {App, IonicApp,Config,Events} from 'ionic/ionic';
import {Http, HTTP_BINDINGS} from "angular2/http";

// pages
import {TabsPage} from './pages/tabs/tabs';
import {MyRoomBookingsPage} from './pages/rooms/myRoomBookings';
import {MyParkingBookingsPage} from './pages/parking/myParkingBookings';
import {KudosPage} from './pages/kudos/kudos';
import {LoginPage} from './pages/login/login';
import {SettingsPage} from './pages/settings/settings'

// providers
import {UserData} from './providers/userData';
import {RoomsData} from './providers/rooms';
import {MyRoomsData} from './providers/myRooms';
import {ParkingData} from './providers/parking';
import {KudosData} from './providers/kudos';
import {MyParkingData} from './providers/myParking';
import {HolidaysData} from './providers/holidays';
import {HolidayNamesData} from './providers/holidayNames';
import {HolidaysByNameData} from './providers/holidaysByName';
import {HolidaysMineData} from './providers/holidaysMine';
import {HolidayEntitlementData} from './providers/holidayEntitlement';

@App({
  templateUrl: 'build/app.html',
  providers: [UserData,KudosData,RoomsData,MyRoomsData,ParkingData,MyParkingData,HolidaysData,HolidayNamesData,HolidaysByNameData,HolidaysMineData,HolidayEntitlementData,Http,HTTP_BINDINGS],
  config: {}
})

class MyApp {
  constructor(app: IonicApp,events: Events, userData: UserData
  ) {
    this.app = app;
    this.events = events;
    this.userData = userData;
    this.root=LoginPage;
    
    // set the side menu options
    this.pages = [
      { title: 'Home', component: TabsPage, icon: 'home', hide: false },
      { title: 'My Room Bookings', component: MyRoomBookingsPage, icon: 'people', hide: false },
      { title: 'My Parking', component: MyParkingBookingsPage, icon: 'car', hide: false },
      { title: 'Kudos Leaderboard', component: KudosPage, icon: 'trophy', hide: false },
      { title: 'Team Connect', component: null, icon: 'contacts', hide: false },
      { title: 'Feedback & Issues', component: null, icon: 'chatboxes', hide: false },
      { title: 'Set Location', component: SettingsPage, icon: 'settings', hide: false},
      { title: 'Logout', component: LoginPage, icon: 'log-out', hide: false }
    ];
    
    // get current location and if it's not Bracknell, hide the
    // parking option
    this.userData.getLocation().then((value) => {
      if (value !== "Bracknell") {
        this.findMenuItemByTitle('My Parking').hide = true;
      }
    });
    
  })
  
  // subscribe to events we want to listen for
  this.subscribeToEvents();
}

subscribeToEvents() {
  // if the user:timeout event occurs, re-open the Login Page
  this.events.subscribe('user:timeout', () => {
    this.openPage({ title: 'Logout', component: LoginPage, icon: 'log-out' });
  });
}


openPage(page) {
  // Team Connect and Feedback & Issues options are special as they are opening
  // an external web page
  if(page.title == "Team Connect") {
    this.app.getComponent('leftMenu').close();
    window.open("https://myserver.com/mobile/homepage/Launcher",  "_blank", "location=no");
  } else if (page.title == "Feedback & Issues") {
    this.app.getComponent('leftMenu').close();
    window.open("https://myserver.com/mobile/forums/Forum?uid=e762f2ed-d469-4ce9-a612-df3efcdc201b", "_blank", "location=no");
  } else {
    // all other pages, set the root to the new page
    // we wouldn't want a back button appearing here
    let nav = this.app.getComponent('nav');
    nav.setRoot(page.component).then(() => {
      // wait for the root page to be completely loaded
      // then close the menu
      this.app.getComponent('leftMenu').close();
    });
  }
  
}

// find a menu option
findMenuItemByTitle(title) {
  return this.pages.find((menuItem) => {
    return menuItem.title === title
  })
}

}

Line 61-64 is weird, why this? that this isn’t necesary there, probably causing an error, also is subscribeToEvents() a function of MyApp or a call of a function inside Constructor? because if it’s the second case it’s out of the constructor:

// subscribe to events we want to listen for
this.subscribeToEvents();
}

If it’s a member of MyApp then should be like this:

// subscribe to events we want to listen for
subscribeToEvents(){}

Thanks - I’ll have to take a look tomorrow (I’m in the UK). I thought I had coded this the same way Ionic do in their app.js in the Conference app so hoped it was best practice (ish) but maybe not. I have a feeling my error is caused by some webpack build / config error though because when I comment out my function at the end of app.js and build again I get the same error but pointing to another function in another file - again complaining about the return type. Thanks for looking at it.

Off course, that bracket } is closing the class before the actual end of the class, so the other methods are just hanging out in the air.

1 Like

Aghh! Yes, you’re right. Not sure how I missed that one - I’d looked at that for ages. Should have done a code auto-indent and I would have spotted it. Thanks @luchillo17