boztek / ember-data-drupal

Ember data support for Drupal 8 CMS (via JSON API module).
MIT License
11 stars 2 forks source link

Field mapping not working #3

Open ArneSaknussemm89 opened 7 years ago

ArneSaknussemm89 commented 7 years ago

So I still don't quite know enough to know where the problem is, but I'm unable to get any field values off my records after getting them. Here is my current environment.js:

drupalEntityModels: {
  "blog-post": {
    entity: 'node',
    bundle: 'blog_post',
    fields: [
      'blogContent',
      'blogImage'
    ]
  },
  "location": {
    entity: 'node',
    bundle: 'location',
    fields: [
      'locationAddress',
      'locationGeolocation',
      'locationDescription',
      'locationType'
    ]
  },
  "product": {
    entity: 'node',
    bundle: 'product',
    fields: [
      'productDesc',
      'productImages',
      'productType'
    ]
  },
  "product-type": {
    entity: 'node',
    bundle: 'product_type',
    fields: [
      'productTypeCategory',
      'productTypeDesc',
      'productTypeImage'
    ]
  },
  "file": {
    entity: 'file',
    bundle: 'file'
  },
  "user": {
    entity: 'user',
    bundle: 'user'
  },
   "square-image": {
      entity: 'media',
      bundle: 'square_image',
      fields: [
        'squareImageImage'
      ]
    },
    "wide-image": {
      entity: 'media',
      bundle: 'wide_image',
      fields: [
        'wideImageImage'
      ]
    }
  }
};

Here is the model for 'blog-post':

import DS from 'ember-data';

const {
  attr,
  belongsTo,
  Model,
} = DS;

export default Model.extend({
  title: attr('string'),
  blogImage: belongsTo('wide-image'),
  blogContent: attr(),
});

And inside a route I am doing this:

import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.get('store').findAll('blog-post');
  }
});

And then when rendering the template I'm doing this:

{{#each model as |blog|}}
  <div class="content">
    {{blog.blogContent}}
  </div>
{{/each}}

But that field is undefined. The title and ID are there, but no field values. If I go inside the ember-data-drupal addon and add console logs inside the service drupal-mapper.js like so:

  entityFor(modelName) {
    console.log(modelName);
    let modelMap = this.map[modelName] || {};
    return modelMap.entity || 'node';
  },

  bundleFor(modelName) {
    console.log(modelName);
    let modelMap = this.map[modelName] || {};
    return modelMap.bundle || modelName;
  },

  fieldName(modelName, fieldName) {
    console.log(modelName);
    let modelMap = this.map[modelName] || {},
        fields = modelMap.fields || [];
    if (fields.includes(fieldName)) {
      return DRUPAL_FIELD_PREFIX + underscore(fieldName);
    }
    return underscore(fieldName);
  }

entityFor and bundleFor both console log out the correct model name, but fieldName console logs out "undefined". This is about as far as I've gotten. Still digging.

left23 commented 7 years ago

Hi @ArneSaknussemm89

I know this issue is a few months old, but I was wondering about your field names in the environment.js file. I was having trouble understanding what was required but I think I can confirm field mapping is working.

drupalEntityModels: {
  "blog-post": {
    entity: 'node',
    bundle: 'blog_post',
    fields: [
      'blogContent',
      'blogImage'
    ]
  },

From what I gather, these field names should reflect the machine names from Drupal.

If you checkout the drupal-mapper.js file, fieldName function returns underscore(fieldName) in order to enable use of these machine names. https://www.emberjs.com/api/classes/Ember.String.html#method_underscore

Typically, Drupal will change camelCase to lowercase when we create a field name via the admin UI, and convert spaces to underscores. See below.

drupal-field-machine-name

drupal-field-machine-name-error

So I think this should work, assuming your Drupal field machine names are blog_post and blog_image. Also reflected in the model and the template.

drupalEntityModels: {
  "blog-post": {
    entity: 'node',
    bundle: 'blog_post',
    fields: [
      'blog_content',
      'blog_image'
    ]
  },

You could use the camelize method to the returned fieldName (in drupal-mapper.js) like return underscore(fieldName).camelize(); but that doesn't make sense as it adds unnecessary processes. I thought I'd mention it anyway, because it helped further my own understanding.

left23 commented 7 years ago

Part II

I just noticed what I describe above is contrary to the README example, where field_related_article is mapped to relatedArticle


// config/environment.js
module.exports = function(environment) {
  var ENV = {
    drupalEntityModels: {
      // Map 'article' ember data model to Drupal entity type 'node'.
      "article": { },
      // Map 'public-event' ember data model to Drupal entity type 'node',
      // entity bundle type 'event'.
      // Also map event model fields 'location' and 'relatedArticle' to
      // 'field_location' and 'field_related_article' payload keys respectively.
      "public-event": { entity: 'node', bundle: 'event', fields: ['location', 'relatedArticle'] },
    }
  }
}
left23 commented 7 years ago

Hi again,

I've dug into this further. My above comments probably highlight my confusion much more than helps others, so apologies for the noise :)

So far, I am able to get the field mapping working when I use the other 2 repos for the front-end demo (ember-drupal-demo-front) and the CMS (ember-drupal-demo-cms).

I've forked the ember-drupal-demo-cms and added some config to replicate @ArneSaknussemm89 's use case with the blog_post content type, and update the Drupal jsonapi module, and the ember-data-drupal addon. All this works. See: https://github.com/left23/ember-drupal-demo-front and https://github.com/left23/ember-drupal-demo-cms

But when I spin up my own ember app, and install the ember-data-drupal addon, I get the same result as @ArneSaknussemm89 describes above.

The main difference that I can see is the addons and versions listed in the package.json file.

Can anyone provide any insight as to how I can approach solving this? Much appreciated :)

ELepolt commented 6 years ago

Hey everyone. I just ran into this issue today that the field_ attributes weren't working.

I noticed that in the serializer line 39 has the following code:

let modelClassString = modelClass.toString(),
        modelName = modelClassString.split(':')[1],
        attributes = {};

modelClassString.toString() was coming back as as "undefined mixin"

I orverwrote extractAttributes and changed that line to

let modelName = modelClass.modelName,
        attributes = {};

Getting a separate problem for relationships, but that's for another day.