Giter VIP home page Giter VIP logo

ember-data-contentful's Introduction

Build Status npm version Ember Observer Score PRs Welcome FastBoot Ready

ember-data-contentful

This is an Ember Data adapter/serializer that uses the READ ONLY Content Delivery API from contentful

Setup in your app

ember install ember-data-contentful

After installing the addon, configure your Contentful Space ID and Access Token inside ENV in config/environment.js:

contentful: {
  space: 'YOUR-CONTENTFUL-SPACE',
  accessToken: 'YOUR-CONTENTFUL-ACCESS-TOKEN',
  previewAccessToken: 'YOUR-CONTENTFUL-PREVIEW-ACCESS-TOKEN',
  usePreviewApi: false,
  environment: 'OPTIONAL CONTENTFUL ENVIRONMENT NAME'
}

You can enable the Preview API for use in development in config/environment.js:

  if (environment === 'development') {
    // ...
    
    ENV.contentful.usePreviewApi = true;
  }

Contentful models

Included are a few models to help with some of the default fields. Here is an example:

// models/post.js
import Contentful from 'ember-data-contentful/models/contentful';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';

export default Contentful.extend({
  author: hasMany('author'),
  body: attr('string'),
  date: attr('date'),
  featuredImage: belongsTo('contentful-asset'),
  slug: attr('string'),
  title: attr('string')
});

will give you the default fields of contentType, createdAt, and updatedAt.

For multi-word model names, you can name your Contentful model IDs with dashes (ie. timeline-post) make sure the contentType field is inferred correctly.

For any relationship property that is a Contentful Asset (image or other media file), use the contentful-asset model. i.e. image: belongsTo('contentful-asset') in order to get the asset correctly.

Adapters and serializers

You will also need to define an adapter and serializer for your model, so that Ember Data knows to fetch data from Contentful instead of your default backend.

// app/adapters/post.js
import ContentfulAdapter from 'ember-data-contentful/adapters/contentful';

export default ContentfulAdapter.extend({});
// app/serializers/post.js
import ContentfulSerializer from 'ember-data-contentful/serializers/contentful';

export default ContentfulSerializer.extend({});

If you are only using Contentful models, you can set these to app/adapters/application.js and app/serializers/application.js to apply for all models.

Usage

Once you have configured your tokens and created your models, you can use the normal Ember Data requests of findRecord, findAll, queryRecord, and query. For example:

model() {
  return this.store.findAll('project');
}

or

model(params) {
  return this.store.findRecord('project', params.project_id);
}

If you want to use pretty urls and the slug field in contentful, you can make your query like so:

model(params) {
  return this.store.queryRecord('page', {
    'fields.slug': params.page_slug
  });
},
serialize(model) {
  return { page_slug: get(model, 'slug') };
}

and ensure that you declare your route in router.js like this:

this.route('page', { path: ':page_slug' });

Previewing Content

Contentful provides a Preview API that allows you to preview unpublished content. In order to enable this, ensure you have your previewAccessToken configured in config/environment.js and enable the usePreviewApi property.

For more information on the contentful Content Delivery API and the available queries, look here: https://www.contentful.com/developers/docs/references/content-delivery-api/

ember-data-contentful's People

Contributors

davidpett avatar ember-tomster avatar fotinakis avatar gpxl avatar jakeleboeuf avatar jonnygreen avatar morganick avatar ryanponce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ember-data-contentful's Issues

Multiple References of Different Content Types

Hey @davidpett, first of all, thanks for building this! I am a pretty new Ember user so please forgive me if this is a really novice question.

How can one go about defining a model that has a field with many references of different content types?

In my case, I have a content type that has a field called "modules". The modules field is a "many reference" field type in Contentful. Specifically, I have set this field up to allow the user to select from one of several different content types.

At the moment, my model looks like this:

import Contentful from 'ember-data-contentful/models/contentful';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';

export default Contentful.extend({
  title: attr('string'),
  subtitle: attr('string'),
  metadata: belongsTo('metadata'),
  modules: hasMany(['module-copy', 'model-testimonials'])
});

Note how there is a modules field that currently allows a user to reference many module-copy, and module-testimonials content types. How can I get this to work? Currently there are no errors, but the models have all undefined content for each field.

Many thanks!

CamelCase Content Models?

Great add-on, thanks for working on this.

If I have a Contentful model such as "TopicArea", I'm not sure how to get Ember to query it correctly. I tried using pathForType to set it, but maybe I'm missing something. Any thoughts?

Thank you!

Error while processing route: index Could not find module `fetch` imported from `ember-data-contentful/adapters/contentful` Error: Could not find module `fetch` imported from `ember-data-contentful/adapters/contentful`

I did a reinstall of my project with ember-data-contentfull. When i spin up my application it won't start. The error in my console is: Error while processing route: index Could not find module fetch imported from ember-data-contentful/adapters/contentful Error: Could not find module fetch imported from ember-data-contentful/adapters/contentful.
When i remove

model() {
  return this.store.findAll('x');
},

It works again. How can i solve this problem? Did i miss something?

401, Auth Error

Hey there, I'm using the add-on and I keep getting 401 "AccessTokenInvalid" errors. Is there a way you could put up the demo ember app on the github, just for reference? I want to make sure I have everything mapped correctly (model/post and config.js).

Thanks!

Meta object from response is empty

The meta object from a response is missing fields such as limit, skip and total that are available as part of contentful's response. I haven't looked into the codebase so is there any way to get that metadata right now? If not, I may submit a PR sometime later.

findAll only returns 100 records & limit is ignored.

store.query('something', {limit: 1000}) works, but store.findAll('something', {limit: 1000}) doesn't and instead always limits to 100 records.

I think the normalizeQueryRecordResponse() method is set up to make the limit work for store.query() and normalizeArrayResponse() isn't helping store.findAll() with the limit feature.

I think the problem is here and that we need something like a normalizeFindAllRecordResponse() method.

https://github.com/davidpett/ember-data-contentful/blob/b4a9ac52496600d88631c82d290de9b7b4f35326/addon/serializers/contentful.js

normalizeFindAllResponse() { return this.normalizeArrayResponse(...arguments); },

Config location

Hey,
So I haven't used an add on with ember before. Where in the config should the contentful params go. I though it would be ENV and I get a build error.

Content Type ID in other notation than Model name does not work correctly

Hi,

I just spent a few hours debugging why the model entries in EmberJS weren't showing up.

In the end I discovered that it has to do with how you name your model vs. how you name your content type ID in contentful.

E.g. with file name of model: faq-entry.js and content type ID of faqEntry, the model is never filled with entries. I had to create a new content type with the id faq-entry for it to work. This is quite confusing, since you can actually specifiy exceptions to the content type ID in the URL in the adapter but this is only used for making the request and not serializing the request.

Includes not loaded when using `queryRecord`

When you query a single record, it doesn't load any of the included records because they are not part of the mutated payload that's passed along:

https://github.com/davidpett/ember-data-contentful/blob/master/addon/serializers/contentful.js#L111

Before I make this change and a subsequent change inside of: https://github.com/davidpett/ember-data-contentful/blob/master/addon/serializers/contentful.js#L143

I would like to add some tests to the add-on specifically around what I'm about to break so we can have some confidence in the changes I'm making.

One thing that I've found really difficult is getting unit tests setup for the serializer; simply because the serializer uses the this.store inside of extractRelationship. (This is something that I've noticed inside of ember-data proper and they have an entire helpers folder dedicated to getting the world (state) setup.)

I'm not quite sure how to approach this. On the one hand we should have a unit test; however, the state needed to do it would be available to us inside of a functional (acceptance) test that uses the dummy app inside the test directory.

I'm a bit new to the JS testing scene, especially inside of an add-on, so I'll continue to read up and see what I can do. Any suggestions?

normalizeResponse must return a valid JSON API document... TypeError: Already read

In _getContent:

  _getContent(type, params) {
   ...
    }).then((response) => {
      return response.json();
    });

The value of response.json()._result is:

TypeError: Already read
    at consumed (http://localhost:4200/assets/vendor.js:102297:29)
    at Response.Body.text (http://localhost:4200/assets/vendor.js:102389:24)
    at Response.Body.json (http://localhost:4200/assets/vendor.js:102416:19)
    at eval (eval at evaluate (unknown source), <anonymous>:1:10)
    at Object.InjectedScript._evaluateOn (<anonymous>:145:85)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:137:25)
    at Object.InjectedScript.evaluateOnCallFrame (<anonymous>:151:143)
    at http://localhost:4200/assets/vendor.js:142544:9
    at tryCatch (http://localhost:4200/assets/vendor.js:63920:14)
    at invokeCallback (http://localhost:4200/assets/vendor.js:63935:15)

This is causing Ember to throw the "normalizeResponse must return a valid JSON API document" error.

Any idea why this error is happening?

The fetch call to Contentful is receiving a 200 back... everything seems fine there. I've tested this in both Firefox and Chrome, and the error is there in both cases.

normalizeResponse must return a valid JSON API document

Not sure what I'm doing wrong. I tried to set up this adapter today, and ran into the following error.

I see contentful.js in the stack trace, so I assume the Contentful adapter is being used.

This error is coming from the following call:

this.store.findRecord('contentful-module', params.entry_id);

I'm using "ember-data": "2.5.0-beta.3",.

ember.debug.js:28535 Error while processing route: secure.program.entry Assertion Failed: normalizeResponse must return a valid JSON API document:
    * One or more of the following keys must be present: "data", "errors", "meta". Error: Assertion Failed: normalizeResponse must return a valid JSON API document:
    * One or more of the following keys must be present: "data", "errors", "meta".
    at new Error (native)
    at Error.EmberError (http://localhost:4200/assets/vendor.js:26695:21)
    at assert (http://localhost:4200/assets/vendor.js:16535:13)
    at Object.assert (http://localhost:4200/assets/vendor.js:26459:34)
    at assert (http://localhost:4200/assets/vendor.js:126323:37)
    at normalizeResponseHelper (http://localhost:4200/assets/vendor.js:133990:39)
    at http://localhost:4200/assets/vendor.js:133739:98
    at Object.Backburner.run (http://localhost:4200/assets/vendor.js:10792:25)
    at _adapterRun (http://localhost:4200/assets/vendor.js:135757:31)
    at http://localhost:4200/assets/vendor.js:133738:20logError @ ember.debug.js:28535defaultActionHandlers.error @ ember.debug.js:28478triggerEvent @ ember.debug.js:28594trigger @ ember.debug.js:53473Transition.trigger @ ember.debug.js:53287(anonymous function) @ ember.debug.js:53107tryCatch @ ember.debug.js:53806invokeCallback @ ember.debug.js:53821publish @ ember.debug.js:53789publishRejection @ ember.debug.js:53724(anonymous function) @ ember.debug.js:32054Queue.invoke @ ember.debug.js:333Queue.flush @ ember.debug.js:397DeferredActionQueues.flush @ ember.debug.js:205Backburner.end @ ember.debug.js:560(anonymous function) @ ember.debug.js:1126setTimeout (async)createAutorun @ ember.debug.js:1124Backburner.defer @ ember.debug.js:770(anonymous function) @ ember.debug.js:32050fulfill @ ember.debug.js:53740resolve @ ember.debug.js:53715resolvePromise @ ember.debug.js:53861reader.onload @ fetch.js:105FileReader (async)readBlobAsText @ fetch.js:121Body.text @ fetch.js:195Body.json @ fetch.js:216(anonymous function) @ contentful.js:194tryCatch @ ember.debug.js:53806invokeCallback @ ember.debug.js:53821publish @ ember.debug.js:53789(anonymous function) @ ember.debug.js:32054Queue.invoke @ ember.debug.js:333Queue.flush @ ember.debug.js:397DeferredActionQueues.flush @ ember.debug.js:205Backburner.end @ ember.debug.js:560(anonymous function) @ ember.debug.js:1126setTimeout (async)createAutorun @ ember.debug.js:1124Backburner.defer @ ember.debug.js:770(anonymous function) @ ember.debug.js:32050fulfill @ ember.debug.js:53740handleMaybeThenable @ ember.debug.js:53700resolve @ ember.debug.js:53713resolvePromise @ ember.debug.js:53861xhr.onload @ fetch.js:379XMLHttpRequest.send (async)(anonymous function) @ fetch.js:400initializePromise @ ember.debug.js:53856Promise @ ember.debug.js:55708self.fetch @ fetch.js:343_getContent @ contentful.js:189findRecord @ contentful.js:65_find @ finders.js:24fetchRecord @ store.js:487_fetchRecord @ store.js:548_flushPendingFetchForType @ store.js:594cb @ ember.debug.js:18384OrderedSet.forEach @ ember.debug.js:18187Map.forEach @ ember.debug.js:18392flushAllPendingFetches @ store.js:537Queue.invoke @ ember.debug.js:333Queue.flush @ ember.debug.js:397DeferredActionQueues.flush @ ember.debug.js:205Backburner.end @ ember.debug.js:560Backburner.run @ ember.debug.js:682Backburner.join @ ember.debug.js:702run.join @ ember.debug.js:21181_emberMetalAssign.default.handleEvent @ ember.debug.js:46707exports.default._emberMetalMixin.Mixin.create._Mixin$create.handleEvent @ ember.debug.js:43655exports.default._emberRuntimeSystemObject.default.extend._bubbleEvent @ ember.debug.js:44742(anonymous function) @ ember.debug.js:44684jQuery.event.dispatch @ jquery.js:4737elemData.handle @ jquery.js:4549

Addon does not work with Contentful 'Location' content type

Contentful provides a content type of 'Location' which appears in the json as a hash with the properties lat and lon.

The serializer does not expect a hash without the sys property, meaning a location type returns true for this clause, which then errors on the next line as the attributeValue has no sys property.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.