Princeton Collins
Princeton Collins

Reputation: 65

Posting form data to MongoDB database with Angular/Nodejs

I'm relatively new to AngularJS, and I decided to build a basic blog app to get familiar with MongoDB and using $http requests.

However, I'm having a bit of trouble using my Angular service to post the data a user fills out in a form on $scope to my MongoDB database.

Originally, I put the $http requests in my controller. This works for me:

mainCtrl.js

  $scope.addPost = function() {
  $http.post('/api/blogs', $scope.formData)
  .success(function(data) {
    $scope.formData = {};
    $location.path('blogs');
    console.log(data, 'Blog created.');
  })     
  .error(function(data) {
    console.log('Error: ' + data);
  })  
};

But this is done through my controller, and I understand this is not best practice, so I am attempting to put this functionality in an Angular service.

Here is the relevant parts of code that make up this part of the app including HTML views:

server.js

//Dependencies.
var express = require('express');
var router = express.Router(); 
var bodyParser = require('body-parser');
var cors = require('cors');
var mongoose = require('mongoose');
var mongojs = require('mongojs');
var http = require('http');
var path = require('path');
var fs = require('fs');
var dotenv = require('dotenv');

var port = 9001;
var mongoUri = 'mongodb://localhost:27017/blog-app';

var app = express();

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());

//Blog Data & Data Storage.
-----------------------------

var Schema = mongoose.Schema;

var blogSchema = new Schema({
   title : {type: String, min: 8, max: 50, required: true},
   body : {type: String, required: true},
   author : {type: String, min: 3, max: 40, required: true},
   pubdate : {type: Date, default: Date.now}
});

var Blog = mongoose.model('Blog', blogSchema);

//Routes.
----------

// GET BLOGS!

app.get('/api/blogs', function(req, res) {
    Blog.find(function (err, blogs) {
        if (err)
            res.send(err);
        res.json(blogs);
    });
});

// POST BLOG!

app.post('/api/blogs', function(req, res) {
    Blog.create({
        title: req.body.title,
        body: req.body.body,
        author: req.body.author,
        date: req.body.date
    }, function(err, blog) {
        if (err)
            res.send(err);
        Blog.find(function(err, blogs) {
            if (err)
                res.send(err);
            res.json(blogs);
        });
    });
});

mainCtrl.js

var app = angular.module("blog-app");

app.controller('MainController', ['mainService', '$scope', '$http',  '$location', '$stateParams', '$state', function(mainService, $scope, $http, $location, $stateParams, $state) { 

  $scope.formData = {};

  $scope.blog = [];

  function getBlogs() {
      mainService.getPosts().then(function(data) {
        $scope.blog = data;
        console.log(data, "The blogs.");
      });
  }

  getBlogs();

  $scope.readPost = function(id) {
      mainService.readPost(id).then(function(data) {
        $scope.readblog = data;
        console.log(data, "This is the blog you selected.")
      });
  };

  $scope.addPost = function(formData) {
      mainService.addPost(formData).then(function() {
        $scope.formData = {};
        $location.path('blogs');
        console.log(data, 'Blog created.');     
      }); 
  };

}]); //End Controller.

mainService.js

var app = angular.module("blog-app");

app.service('mainService', function($http, $q) {

    var blog = [];
    var readblog = {};
    var formData = {};

    this.getPosts = function() {
        return $http.get('/api/blogs').then(function(response){
            blog = response.data;
            return blog;
        });
    }

    this.readPost = function(id) {
        return $http.get('/api/blogs/' + id).then(function(response) {
            readblog = response.data;
            return readblog;
      });
    };

    this.addPost = function(formData) {
        $http.post('/api/blogs', formData);
    };

  });

newblog.html

<div class="newblog">
    <a ui-sref="blogs"><i class="fa fa-close fa-2x exit"></i></a>
    <div class="form">
          <form>
                <i class="fa fa-pencil-square-o fa-5x"></i><br>

                <input class="blogtitle" type="text" ng- model="formData.title" placeholder="Blog Title" required /><br>

                <textarea ng-model="formData.body" rows="15" placeholder="Write the body of your blog here." required></textarea><br>

                <label for="">by:</label><br>
                <input class="blogauthor" type="text" ng-model="formData.author" placeholder="Author Name" required /><br><br>

                <button type="submit" ng- click="addPost()">Submit</button> 
          </form>
    </div>
</div>

So...

...to be clear, I want to be able to click on the button in newblog.html with the addPost() function, and have it put the form data in my database. What is not clear to me is how to reference the data that the user inputs in the $scope, within my service, so I can actually post it to the database, or if this is even possible. Was easy enough to do this in the controller(shown in example at very of post), but I would like to do it in the service.

What I have tried:

Service Function

this.addPost = function(formData) {
    $http.post('/api/blogs', formData).then(function(response) {
        blog.push(response.data);
        return blog;
    })
};

and then...

Controller Function

$scope.addPost = function(data) {
  mainService.addPost(data).then(function(data) {
    $scope.blog.push(data);
    console.log(data, 'Blog created.');     
  }); 
};

I can't remember what else I had tried, but ultimately, it was to no avail. I'm guessing that it might be something very simple I possibly overlooked while on my Google search quest. Any help would be appreciated, will also clarify on anything that didn't quite make sense. Will continue to work on it and fix/answer question if I find anything.

Upvotes: 2

Views: 4654

Answers (1)

Lex
Lex

Reputation: 7194

Your controller function should be:

$scope.addPost = function() {
    mainService.addPost($scope.formData).then(function() {
        $scope.formData = {};
        $location.path('blogs');
        console.log(data, 'Blog created.');     
    }); 
};

You're not passing anything from the view so essentially you were calling mainService.addPost with a null value for formData.

Update

I missed this when first reading your question, but the service method needs to return the promise:

this.addPost = function(formData) {
    return $http.post('/api/blogs', formData);
};

Upvotes: 2

Related Questions