0

I forked this really nice repo https://github.com/loicknuchel/ionic-starter

and started to translate the app to coffee script. Almost everything worked well but with the file: https://github.com/loicknuchel/ionic-starter/blob/master/www/js/common/parse-utils.js

which I converted to this:

angular.module 'app'

.provider 'ParseUtils', ->
  credentials =
    applicationId: null
    restApiKey: null

  this.initialize = (applicationId, restApiKey) ->
    credentials.applicationId = applicationId
    credentials.restApiKey = restApiKey

  this.$get = ($http, $q, CrudRestUtils, Utils) ->
    service =
      createCrud: createCrud
      createUserCrud: createUserCrud
      signup: signup
      login: login
      loginOAuth: loginOAuth
      passwordRecover: passwordRecover
      toGeoPoint: toGeoPoint
      toPointer: toPointer
      toDate: toDate
    parseUrl = 'https://api.parse.com/1'
    parseObjectKey = 'objectId'

    getParseData = (result) ->
      if result and result.data
        if !result.data[parseObjectKey] and result.data.results
          return result.data.results
        else
          return result.data


    parseHttpConfig = headers:
      'X-Parse-Application-Id': credentials.applicationId
      'X-Parse-REST-API-Key': credentials.restApiKey

    createCrud = (objectClass, _processBreforeSave, _useCache) ->
      endpointUrl = parseUrl + '/classes/' + objectClass
      service = CrudRestUtils.createCrud(endpointUrl, parseObjectKey, getParseData, _processBreforeSave, _useCache,
        parseHttpConfig)

      service.savePartial = (objectToSave, dataToUpdate) ->
        objectId = if typeof objectToSave == 'string' then objectToSave else objectToSave[parseObjectKey]
        toUpdate = angular.copy(dataToUpdate)
        toUpdate[parseObjectKey] = objectId
        service.save toUpdate

      service

    createUserCrud = (sessionToken, _processBreforeSave, _useCache) ->
      endpointUrl = parseUrl + '/users'
      parseUserHttpConfig = angular.copy(parseHttpConfig)
      parseUserHttpConfig.headers['X-Parse-Session-Token'] = sessionToken

      _processBreforeSaveReal = (user) ->
        delete user.emailVerified
        if _processBreforeSave
          _processBreforeSave user


      service = CrudRestUtils.createCrud(endpointUrl, parseObjectKey, getParseData, _processBreforeSaveReal, _useCache,
        parseUserHttpConfig)

      service.savePartial = (objectToSave, dataToUpdate) ->
        objectId = if typeof objectToSave == 'string' then objectToSave else objectToSave[parseObjectKey]
        toUpdate = angular.copy(dataToUpdate)
        toUpdate[parseObjectKey] = objectId
        service.save toUpdate

      return service

    # user MUST have fields 'username' and 'password'. The first one should be unique, application wise.

    signup = (user) ->
      if user and user.username and user.password
        $http.post(parseUrl + '/users', user, parseHttpConfig).then (result) ->
          newUser = angular.copy(user)
          delete newUser.password
          newUser.objectId = result.data.objectId
          newUser.sessionToken = result.data.sessionToken
          newUser
      else
        $q.reject data:
          error: 'user MUST have fields username & password !'

    login = (username, password) ->
      $http.get(parseUrl + '/login?username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password),
        parseHttpConfig).then (result) ->
          result.data

    # https://parse.com/docs/rest#users-linking

    loginOAuth = (authData) ->
      $http.post(parseUrl + '/users', {authData: authData}, parseHttpConfig).then (result) ->
        result.data

    passwordRecover = (email) ->
      $http.post(parseUrl + '/requestPasswordReset', {email: email}, parseHttpConfig).then ->
# return nothing


    toGeoPoint = (lat, lon) ->
      {
      __type: 'GeoPoint'
      latitude: lat
      longitude: lon
      }

    toPointer = (className, sourceObject) ->
      {
      __type: 'Pointer'
      className: className
      objectId: if typeof sourceObject == 'string' then sourceObject else sourceObject[parseObjectKey]
      }

    toDate = (date) ->
      d = Utils.toDate(date)
      if d
        return d.toISOString()
      throw 'Function toDate must be used with a timestamp or a Date object'

but with that I only get the error:

Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:pget] Provider 'ParseUtils' must define $get factory method.

But i declare the $get method...

EDIT:

This is a repo with the code https://github.com/bambamboole/ionic-bootstrap

this is the in js compiled coffee file:

angular.module('app').provider('ParseUtils', function() {
  var credentials;
  credentials = {
    applicationId: null,
    restApiKey: null
  };
  this.initialize = function(applicationId, restApiKey) {
    credentials.applicationId = applicationId;
    return credentials.restApiKey = restApiKey;
  };
  return this.$get = function($http, $q, CrudRestUtils, Utils) {
    var createCrud, createUserCrud, getParseData, login, loginOAuth, parseHttpConfig, parseObjectKey, parseUrl, passwordRecover, service, signup, toDate, toGeoPoint, toPointer;
    service = {
      createCrud: createCrud,
      createUserCrud: createUserCrud,
      signup: signup,
      login: login,
      loginOAuth: loginOAuth,
      passwordRecover: passwordRecover,
      toGeoPoint: toGeoPoint,
      toPointer: toPointer,
      toDate: toDate
    };
    parseUrl = 'https://api.parse.com/1';
    parseObjectKey = 'objectId';
    getParseData = function(result) {
      if (result && result.data) {
        if (!result.data[parseObjectKey] && result.data.results) {
          return result.data.results;
        } else {
          return result.data;
        }
      }
    };
    parseHttpConfig = {
      headers: {
        'X-Parse-Application-Id': credentials.applicationId,
        'X-Parse-REST-API-Key': credentials.restApiKey
      }
    };
    createCrud = function(objectClass, _processBreforeSave, _useCache) {
      var endpointUrl;
      endpointUrl = parseUrl + '/classes/' + objectClass;
      service = CrudRestUtils.createCrud(endpointUrl, parseObjectKey, getParseData, _processBreforeSave, _useCache, parseHttpConfig);
      service.savePartial = function(objectToSave, dataToUpdate) {
        var objectId, toUpdate;
        objectId = typeof objectToSave === 'string' ? objectToSave : objectToSave[parseObjectKey];
        toUpdate = angular.copy(dataToUpdate);
        toUpdate[parseObjectKey] = objectId;
        return service.save(toUpdate);
      };
      return service;
    };
    createUserCrud = function(sessionToken, _processBreforeSave, _useCache) {
      var _processBreforeSaveReal, endpointUrl, parseUserHttpConfig;
      endpointUrl = parseUrl + '/users';
      parseUserHttpConfig = angular.copy(parseHttpConfig);
      parseUserHttpConfig.headers['X-Parse-Session-Token'] = sessionToken;
      _processBreforeSaveReal = function(user) {
        delete user.emailVerified;
        if (_processBreforeSave) {
          return _processBreforeSave(user);
        }
      };
      service = CrudRestUtils.createCrud(endpointUrl, parseObjectKey, getParseData, _processBreforeSaveReal, _useCache, parseUserHttpConfig);
      service.savePartial = function(objectToSave, dataToUpdate) {
        var objectId, toUpdate;
        objectId = typeof objectToSave === 'string' ? objectToSave : objectToSave[parseObjectKey];
        toUpdate = angular.copy(dataToUpdate);
        toUpdate[parseObjectKey] = objectId;
        return service.save(toUpdate);
      };
      return service;
    };
    signup = function(user) {
      if (user && user.username && user.password) {
        return $http.post(parseUrl + '/users', user, parseHttpConfig).then(function(result) {
          var newUser;
          newUser = angular.copy(user);
          delete newUser.password;
          newUser.objectId = result.data.objectId;
          newUser.sessionToken = result.data.sessionToken;
          return newUser;
        });
      } else {
        return $q.reject({
          data: {
            error: 'user MUST have fields username & password !'
          }
        });
      }
    };
    login = function(username, password) {
      return $http.get(parseUrl + '/login?username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password), parseHttpConfig).then(function(result) {
        return result.data;
      });
    };
    loginOAuth = function(authData) {
      return $http.post(parseUrl + '/users', {
        authData: authData
      }, parseHttpConfig).then(function(result) {
        return result.data;
      });
    };
    passwordRecover = function(email) {
      return $http.post(parseUrl + '/requestPasswordReset', {
        email: email
      }, parseHttpConfig).then(function() {});
    };
    toGeoPoint = function(lat, lon) {
      return {
        __type: 'GeoPoint',
        latitude: lat,
        longitude: lon
      };
    };
    toPointer = function(className, sourceObject) {
      return {
        __type: 'Pointer',
        className: className,
        objectId: typeof sourceObject === 'string' ? sourceObject : sourceObject[parseObjectKey]
      };
    };
    return toDate = function(date) {
      var d;
      d = Utils.toDate(date);
      if (d) {
        return d.toISOString();
      }
      throw 'Function toDate must be used with a timestamp or a Date object';
    };
  };
});
bambamboole
  • 577
  • 10
  • 30

1 Answers1

0

The Coffeescript parser uses the last sentence of a function as the return of the function, the this.$get definition is the last block of your function so it's being returned, so it's not part of the Provider function.

You can fix this by adding the return keyword at the end of the function block:

this.$get = (...) ->
#inside the $get definition...
    toDate = (date) ->
      d = Utils.toDate(date)
      if d
        return d.toISOString()
      throw 'Function toDate must be used with a timestamp or a Date object'
    #still inside the $get function block
    return
#we're outside the $get function block, same indentation level...
return

now your code will return a function and the error will be gone

fixmycode
  • 8,220
  • 2
  • 28
  • 43
  • hmm This doesn't work for me... I can't get in in a fiddle, because of the compilation etc, but I published a repo with the source code. https://github.com/bambamboole/ionic-bootstrap – bambamboole Sep 06 '15 at 15:19
  • in the coffeescript website, there's a section called "try coffeescript", it's a console with live JavaScript transcoding. Try pasting your code and see the result. – fixmycode Sep 06 '15 at 16:58
  • then can you update your answer with the generated JavaScript? – fixmycode Sep 06 '15 at 17:05
  • can you see what's happening now? your function is returning the get definition. Add the return at the end as it's shown in my answer and generate it again. – fixmycode Sep 06 '15 at 17:14
  • also, I can see the same thing happening inside the get function with the toDate definition, you may want to add a return statement to the end of the $get block as well – fixmycode Sep 06 '15 at 17:17
  • hmm I tried any possible returns, but this does not work. – bambamboole Sep 06 '15 at 17:20