0
votes

When trying to do a post from a component in my ember app to my express api I am receiving

SyntaxError: Unexpected token V in JSON at position 0

When checking what response I'm receiving in the network inspector on chrome I see

ValidationError: body: Path `body` is required., title: Path `title` is required. undefined



The blogpost.title and .body both return the correct values but the blogpost gives me

adapterError: SyntaxError: Unexpected token V in JSON at position 0 at parse

EmberApp/App/Components/create-new-post/Component.js

export default Component.extend({
  blogpost: null,
  router: inject('-routing'),
  actions: {

    save: function (blogpost) {
      console.log(blogpost.title);
      console.log(blogpost.title);
      console.log(blogpost);

      blogpost.save()
          .then(
            (value) => {
              Ember.Logger.info(value);
              this.get('router').transitionTo('index')
            }
          )
          .catch(
            (err) => {
              Ember.Logger.info('failure to save');
              console.log(err);
            }
          )

    }
  }
});

EmberApp/App/Components/create-new-post/template.hbs

<form  {{action "save" blogpost on="submit"}}>
  <p>
    {{input name="title" value=blogpost.title class="form-control" placeholder="Title"}}
  </p>
  <p>
    {{textarea name="body" value=blogpost.body class="form-control" placeholder="Body" rows="10" cols="140"}}
  </p>
  <p>
    <button class="btn btn-primary btn-block" type="submit" value="Save">Publish</button>
  </p>
</form>

EmberApp/App/routes/createpost.js

import Route from '@ember/routing/route';

export default Route.extend({
  model() {
    return this.store.createRecord('blogpost');
  }

});

EmberApp/App/templates/createpost.hbs

<div class="container">
  <div class="col-sm-12 pull-left">
    {{create-new-post blogpost=model }}
  </div>
</div>

I have confirmed that the api route for post is working with postman so I'm not sure what the issue is with ember.

ExpressAPI router

router.post('/blogposts',  (req, res) => {
    console.log('In router');
    console.log(req.body);
    let newBlogPost = new BlogPostSchema(req.body);

    newBlogPost.save((err, blogpost) => {
        if(err){
            console.log(err +" "+blogpost);
            res.send(err +" "+blogpost);
        }
        console.log(blogpost);
        res.json(blogpost);
    });
});

req.body returns {} which is why it hits err

1
Can you share the JSON that you send in the post request? And are you able to use a debugger in your express app? - Aakash Malhotra
it looks like your express server isn't returning json? - NullVoxPopuli
Edited question to include the express api router. req.body returns {} which in turn leads to ValidationError: body: Path body is required., title: Path title is required. undefined - dmp5658
is your backend new? if so, I wonder if it'd be more worth while to start with one of these: jsonapi.org/implementations/#server-libraries-node-js. but from your snippet it looks like you aren't catching errors. you'll need to do that in order to format the errors as json. - NullVoxPopuli
I'm now sending the error as json which fixed the error but it still gives me ValidationError: body: Path body` is required., title: Path title is required. undefined` Which is why the err is happening. blogpost.title and blogpost.body both return the correct values but blogpost returns {} - dmp5658

1 Answers

0
votes

Figured out my issue. For anyone who has similar issues when trying use an express api with ember as the frontend first I realized that post requests from emberjs sends a header with "application/vnd.api+json" content type.

So in my express server.js I added app.use(bodyParser.json({ type: 'application/vnd.api+json' })); which lets body parser parse and return the correct req.body. I then created a new serializer ember generate serializer blogpost for my ember app which serialized the request to the format my express api was expecting.

EmberApp/Serializers/blogpost.js

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  serialize(snapshot, options){
    let json = this._super(...arguments);
    let newjson = {
      title: json.data.attributes.title,
      body:  json.data.attributes.body
    };

    return newjson;
  }
});