Search code examples
angularjsnode.jsangular-ui-routerangular-fullstack

structuring angular fullstack api function callbacks


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]

Solution

  • 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