0

I'm new to yeoman's angular fullstack and seem to be structuring my server api callbacks incorrectly. I have hacked together some code. I know this is wrong but I've hit a wall - any advice would be appreciated:

for example, if I make a simple win32ole iTunes com call and return a filepath:

GET call in client/app/main.controller.js

  $http.get('/api/iTunes/getxmlpath').success(function(path) {
    $scope.myfilepath = path;
  });

routing is set up in server/api/iTunes/index.js

router.get('/getxmlpath', controller.getxmlpath);

relevant part of server/api/iTunes/iTunes.controller.js

exports.getxmlpath = function(req, res) {
  getWin32OlePath(serviceCallback);
};

function getWin32OlePath() {
  try {
    var win32ole = require('win32ole');
    var iTunesApp = win32ole.client.Dispatch('iTunes.Application');
    var xmlpath = iTunesApp.LibraryXMLPath();
    console.log('got itunes xml path: '+xmlpath);
    return res.json(200, xmlpath);
  } catch (err) {
    return handleError(res, err);
  }
}


/********
error handle the callbacks
**********/
var serviceCallback =
function(response){
  return function(err, obj){
    if(err) {
      response.send(500);
    } else {
        response.send(obj);
      }
    }
  }

grunt server fails with

  Error: Route.get() requires callback functions but got a [object Undefined]
John Paul Vaughan
  • 205
  • 1
  • 3
  • 9

1 Answers1

0

From what I see, there could be several issues with the code above. I will be using lowercase for the filenames and controller so itunes instead of iTunes:

  1. Did you define the routes and controller in server/routes.js?

    app.use('/api/itunes', require('./api/itunes'));

  2. In server/itunes/itunes.controller.js you lose scope of the respond object res you could change the code accordingly:

    exports.getxmlpath = function(req, res) {
      var xmlpath = getWin32OlePath(serviceCallback);
      return res.json(200, xmlpath);
    };
    
    function getWin32OlePath() {
      var xmlpath = ''; // what ever you are doing here
    
      // do the things you need to do in your function
    
      return xmlpath;
    }
    
  3. Is you server/itunes/index.js complete?

    'use strict';
    
    var express = require('express');
    var controller = require('./itunes.controller');
    var router = express.Router();
    
    router.get('/getxmlpath', controller.getxmlpath);
    
    module.exports = router;
    

Another hint: to easily create working endpoints with yeoman you can use the generator from terminal:

yo angular-fullstack:endpoint itunes

More is explained in the angular.fullstack documentation: https://github.com/DaftMonk/generator-angular-fullstack

Rias
  • 1,956
  • 22
  • 33
  • Thanks for your advice. I understand it more and It's working perfectly now. The serviceCallback function seemed to have no effect, but after digging a bit deeper but I think the fullstack already handles errors automatically with handleError() so I just removed it and didn't use a callback. – John Paul Vaughan Mar 05 '15 at 04:48
  • Glad it helped. What exactly did you want to achieve with the service callback? Do you have an example or the tutorial you got that from? – Rias Mar 05 '15 at 09:25
  • 1
    The plan it to parse a local iTunes library and then augment that information with information from echonest or similar providers. I've pretty much just pieced it together from snippets around the web. the yeoman endpoint generator clarifies what is best practice for me, thanks for the tip. – John Paul Vaughan Mar 07 '15 at 09:53