mercredi 18 octobre 2017

EmberJS Express API | Error: Assertion Failed: 'note' was saved to the server, but the response does not have an id and your record does not either

Fix one problem and get another right?
Using EmberJS, I have an API that is working fully based on the testing with Postman. I am now trying to incorporate it into an EmberJS project and am having issues with updating the database.
It seems that the EmberData is being updated, duplicated, but not updated in the database. I get this error after I call note.save();

Here is my file structure:
api
- -controllers
- - - - noteController.js
- -models
- - - - noteModel.js
- -node_modules
- -routes
- - - - noteRoute.js
- -package-lock.json
- -package.json
- -server.js
app
- - adapters
- - - - application.js
- - - - note.js
- - controllers
- - - - note
- - - - - - edit.js
- - models
- - - - note.js
- - routes
- - - - note
- - - - - - edit.js
- - - - notes.js
- - serializers
- - - - note.js
- - templates
- - - - note
- - - - - - edit.hbs
- - - - notes.hbs
config
dist
node_modules
public
server
etc...


Here are the files I believe that will be of use to solving this problem.

api>controllers>noteController.js

'use strict';

let mongoose = require('mongoose'),
    Note = mongoose.model('Notes');

exports.list_all_notes = function(req, res){
    Note.find({}, function(err, note){
        if (err)
            res.send(err);
        else
            res.json(note);
    });
};

exports.create_a_note = function(req, res){
    let new_note = new Note(req.body);
    new_note.save(function (err, note){
        if (err)
            res.send(err);
        else
            res.json(note);
    });
};

exports.update_a_note = function(req, res){
    Note.findById(req.params._id, function(err, note){
        if (err)
            res.status(500).send(err)
        else{
            note.title = req.body.title || note.title;
            note.content = req.body.content || note.content;
            note.author = req.body.author || note.author;

            //save to db
            note.save((err, note) => {
                if (err) {
                    res.status(500).send(err);
                }
                res.status(200).send(note);
            });
        }
    });
}

exports.read_a_note = function(req, res){
    Note.findById(req.params._id, (err, note) => {
        if (err) {
            res.status(500).send(err)
        }
        if (note) {
            res.status(200).send(note)
        } else {
            res.status(404).send("No note found with that ID")
        }
    }
)};

exports.delete_a_note = function(req, res){
    Note.remove({
        _id: req.params.noteId
    }, function(err, task){
        if (err)
            res.send(err);
        else
            res.json({ message: 'Note successfully deleted.' });
    });
};

api>models>noteModel.js

'use strict'

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

let NoteSchema = new Schema({
    title: { 
        type: String, 
        required: true
    },
    content: { 
        type: String 
    },
    author: { 
        type: String 
    }
});

module.exports = mongoose.model('Notes', NoteSchema);

api>routes>noteRoute.js

'use strict';

let router = require('express').Router();
let note = require('../controllers/noteController');

//router.post('/:_id', note.create_a_note);
//router.post('/', note.create_a_note);
router.patch('/', note.update_a_note);
router.get('/', note.list_all_notes);

router.get('/:_id', note.read_a_note);
router.put('/:_id', note.update_a_note)
router.delete('/notes/:_id', note.list_all_notes);

module.exports = router;

api>server.js

var express = require('express'),
    app = express(),
    port = process.env.PORT || 4500,
    mongoose = require('mongoose'),
    Note = require('./models/noteModel'), //created model loading here
    bodyParser = require('body-parser');

// Allow POST, GET, PUT, DELETE, OPTIONS
app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, PATCH, DELETE, OPTIONS');
    next();
});

//DB Vars
var uri = 'mongodb://localhost/AccurateEmber2';

// mongoose instance connection url connection
mongoose.Promise = global.Promise;

var options = {
    useMongoClient: true
};
mongoose.connect(uri, function (err) {
    if (err) {
        console.log('ERROR connecting to: ' + uri + '. ' + err);
    } else {
        console.log('Succeeded connected to: ' + uri);
    }
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());


var noteR = require('./routes/noteRoute'); //importing route
app.use('/notes', noteR);
app.use('/notes/:_id', noteR);

//middleware catch
app.use(function (req, res) {
    res.status(404).send({ url: req.originalUrl + ' not found' })
});

app.listen(port);


console.log('todo list RESTful API server started on: ' + port);


app>adapters>application.js
import DS from 'ember-data';

//import JSONAPIAdapter from 'ember-data/adapters/json-api';

export default DS.RESTAdapter.extend({
    host: 'http://localhost:4500'
});

app>adapters>note.js

import ApplicationAdapter from './application';

export default ApplicationAdapter.extend({
    pathForType() {
        return 'notes';
    }
});

app>controllers>note>edit.js

import Ember from 'ember';

export default Ember.Controller.extend({
    actions: {
        save: function () {
            const title = this.get('model.title');
            const content = this.get('model.content');
            const author = this.get('model.author');
            const id = this.get('model.id');

            var note = this.store.createRecord('note', {
                title: title,
                content: content,
                author: author
            });
            note.save();
            this.transitionToRoute('notes');
        },
        del: function () {
            //this.get('model').deleteRecord();
            let d = this.get('model');
            d.destroyRecord();
            d.save();
            //this.get('model').save();
            this.transitionToRoute('notes');

        }
    }
});

app>models>note.js

    import DS from 'ember-data';

    const {
        attr
    } = DS;

    export default DS.Model.extend({
        title: attr('string'),
        content: attr('string'),
        author: attr('string')
    });
app>routes>note>edit.js  
    import Ember from 'ember';

    export default Ember.Route.extend({
    });

app>routes>notes.js

import Ember from 'ember';

const {
  set,
  Route,
    inject: {
  }
} = Ember;

export default Route.extend({
    model() {
        return this.store.findAll('note');
    },

    //Overwrite
    //Allows us to use "notes" in notes.hbs rather than "model" in the  call.
    setupController(controller, model) {
        set(controller, 'notes', model);
    }
});

app>serializers>note.js

import DS from 'ember-data';

export default DS.RESTSerializer.extend({
    normalizeResponse(store, primaryModelClass, payload, id, requestType){      
        let isArr = Object.prototype.toString.call(payload) == '[object Array]';
        if (!isArr){
            payload = { notes: payload };
            payload.notes.id = payload.notes._id;
            delete payload.notes._id;
        }else{
        payload = {notes: payload};
            payload.notes.forEach(function(note) {
                note.id = note._id;
                delete note._id;
            }, this);
        }
        return this._super(store, primaryModelClass, payload, id, requestType);
    }  
});

app>templates>note>edit.hbs

<div class="container">
    <div class="row">
        <h2> Edit Note</h2>
        <form >
            <dl>
                <dt>
                    <p>ID:</p> 
                </dt>
                <dt>
                    <p>Title:</p> 
                </dt>
                <dt>
                    <p>Content:</p> 
                </dt>
                <dt>
                    <p>Author:</p> 
                </dt>
            </dl>
            <div class="row">
                <button type="submit" class="btn btn-primary">Done</button>
                <button type="delete" class="btn btn-primary" >Destroy</button>
            </div>
        </form>
    </div>
</div>

app>templates>notes.hbs

<div class="container">
    <div class="row">
            <h1>Notes</h1>
             
            <h3></h3>
            
            <p>
                <br>By: </p>
            
        
    </div>
</div>




Aucun commentaire:

Enregistrer un commentaire