Search code examples
angularjsmeanjs

ng-file-upload not hitting correct endpoint


I am using MEANJS. I am using ng-file-upload in my client to upload a file. The problem is that in the url I have defined for the upload, there are no parameters in it but when hitting the endpoint, it invokes the function where it thinks there is a parameter in it. This upload is being done on the creation of a new activity (activities are the same structure as the default articles)

Controller:

function save(isValid) {
    Upload.upload({
        url: 'api/activities/gpxData', // no optional parameter ':activityId'
        data: {
            file: $scope.gpxData
        }
        }).then(function(resp) {
            console.log(resp);
        }, function(resp) {
            console.log(resp)
        }, function(evt) {

        }
    });     
}

These are all my route's defined:

app.route('/api/activities').all(activitiesPolicy.isAllowed)
    .get(activities.list)
    .post(activities.create);

app.route('/api/:userId/activities').all(activitiesPolicy.isAllowed)
    .get(activities.usersActivities)
    .post(activities.create);

app.route('/api/activities/:activityId').all(activitiesPolicy.isAllowed)
    .get(activities.read)
    .put(activities.update)
    .delete(activities.delete);

app.route('/api/:userId/activities/:activityId').all(activitiesPolicy.isAllowed)
    .get(activities.read)
    .put(activities.update)
    .delete(activities.delete);

app.route('/api/activities/gpxData').all(activitiesPolicy.isAllowed)
    .post(activities.uploadGpx);

// Finish by binding the Activity middleware
app.param('activityId', activities.activityByID);

Even though there is no optional parameter (activityId) being passed in the url, the function activities.activityByID is invoked which is this:

exports.activityByID = function (req, res, next, id) {
    if (!mongoose.Types.ObjectId.isValid(id)) {
        return res.status(400).send({
            message: 'Activity is invalid'
        });
    }
};

Also, there is an id being passed in (which is the id of the activity being created) but I do not know where from and it is not a valid id as it has not yet been entered into mongo.


Solution

  • It is caused by routing ordering in your express code. because /api/activities/gpxData fits to pattern /api/activities/:activityId. The routing stops on the first matching rule and execute. This is standard implementation of routing in various technologies.

    Move

    app.route('/api/activities/gpxData').all(activitiesPolicy.isAllowed)
       .post(activities.uploadGpx);
    

    before

    app.route('/api/activities/:activityId').all(activitiesPolicy.isAllowed)
       .get(activities.read)
       .put(activities.update)
       .delete(activities.delete);
    

    and then try to run.