Trouble upgrading to Ember/Ember-Data 2.0 - ember.js

I have an ember-cli project, and I'm trying to get to ember 2.0. I know the idea is to remove all deprecation warning before upgrading, but I don't know what to do about this one:
DEPRECATION: The default behavior of shouldReloadAll will change in Ember Data 2.0
to always return false when there is at least one "foo" record in the store.
If you would like to preserve the current behavior please override shouldReloadAll
in your adapter:application and return true.
[deprecation id: ds.adapter.should-reload-all-default-behavior]
This warning is related to a call that I make for this.store.findAll('foo') for example.
As far as I can understand, fixing this would involve change the behavior of either ember-data or ember-django-adapter.
Here is my (partial) package.json:
{
"name": "my-app",
"private": true,
"devDependencies": {
"ember-cli": "1.13.13",
"ember-data": "1.13.15",
"ember-django-adapter": "^1.1.1",
}
}
Here is a some of my bower.json:
{
"name": "my-app",
"dependencies": {
"ember": "1.13.11",
"ember-data": "1.13.15",
"ember-resolver": "~0.1.20",
}
}
So, after reading a bit, I thought maybe I can just ignore this warning, and maybe the behavior of shouldReloadAll isn't all that important for my app.
I'll list my steps carefully, because I'm not very familiar with npm or bower, and I may well be doing something wrong.
Change ember and ember-data to "~2.0.0" wherever they occur in package.json and ember.json
npm uninstall ember-data
bower uninstall ember-data
bower uninstall ember
npm cache clear
bower cache clear
npm install
bower install
At this point it is telling me that I have installed ember-data#2.0.1 and ember#2.0.2
I then run the application, and find the following error:
TypeError: str.replace is not a function
at Object.func (ember.debug.js:35278)
at Object.Cache.get (ember.debug.js:12867)
at decamelize (ember.debug.js:35320)
at Object.func (ember.debug.js:35235)
at Object.Cache.get (ember.debug.js:12867)
at Object.dasherize (ember.debug.js:35324)
at ember$data$lib$system$normalize$model$name$$normalizeModelName (normalize-model-name.js:13)
at ember$data$lib$serializers$json$serializer$$default.extend.modelNameFromPayloadKey (rest-serializer.js:426)
at ember$data$lib$serializers$json$serializer$$default.extend._normalizePolymorphicRecord (rest-serializer.js:161)
at rest-serializer.js:141onerrorDefault # ember.debug.js:29661exports.default.trigger # ember.debug.js:51067(anonymous function) # ember.debug.js:52059Queue.invoke # ember.debug.js:978Queue.flush # ember.debug.js:1042DeferredActionQueues.flush # ember.debug.js:838Backburner.end # ember.debug.js:166Backburner.run # ember.debug.js:288run # ember.debug.js:19125hash.success # rest-adapter.js:735fire # jquery.js:3148self.fireWith # jquery.js:3260done # jquery.js:9314callback # jquery.js:9718
The following versions are reported:
DEBUG: -------------------------------
vendor.js:15777 DEBUG: Ember : 2.0.2
vendor.js:15777 DEBUG: Ember Data : 2.0.1
vendor.js:15777 DEBUG: jQuery : 1.11.3
vendor.js:15777 DEBUG: -------------------------------
vendor.js:19380 Rendering application with bracketfun-web#view:toplevel: Object
PLEASE NOTE: This error doesn't seem related to the deprecation, in any explanation of the deprecation that I've received.

You need to create your application adapter by using ember generate drf-adapter application from the command line. This should create the file app/adapters/application.js, to which you will add the override of shouldReloadAll(), and the end result should look something like this:
import DRFAdapter from './drf';
export default DRFAdapter.extend({
shouldReloadAll() {
return true;
}
});
EDIT: replace error.
If you look at the stack trace and see where the error is coming from, you'll see it's originating from the serializer. It's struggling to get the model name from the payload. This is most likely due to the fact that you have not set up your application serializer.
You can generate the serializer using ember generate drf-serializer application. This will create the file app/serializers/application.js.
Remember Ember does not know to implicitly use an adapter / serializer by simply installing the add on, you need to tell it to use them by creating an application adapter and serializer.

Related

How to enable ds-rollback-attribute in ember?

Ember has method rollbackAttribute() which is very similar to the default method rollbackAttributes(). The difference is rollbackAttribute() can be used to rollback ONLY specific model attribute.
By default this method is not available and to use it you need to enable ds-rollback-attribute and run the canary build as written here: https://docs.w3cub.com/ember/classes/ds.model/methods/#rollbackAttribute
Where can I enable the ds-rollback-attribute and how can I ran the canary build?
I fear you are looking at non-official and outdated API docs. The API docs for Ember Data are hosted here: https://api.emberjs.com/ember-data/release
The rollbackAttribute() method is not documented anymore for the latest release, which is 3.13 at the time writing this. It was last documented for 3.1. I think it was removed as a stale feature flag in this PR: [FEAT] remove all stale feature flags #5384
Actually the implementation of the rollbackAttribute() is quite simple.
We can create our own method and extract it into the service.
app/services/rollback-attribute.js
import Ember from 'ember';
export default Ember.Service.extend({
rollback(model, attribute) {
const changedAttributes = model.changedAttributes();
if (changedAttributes[attribute]) {
model.set(attribute, changedAttributes[attribute][0]);
}
}
});
After creating this service you can use it for example in the route.js
import Ember from 'ember';
import service from 'ember-service/inject';
export default Ember.Route.extend({
rollbackAttribute: service('rollback-attribute'),
_rollbackAttribute(model, attribute) {
this.get('rollbackAttribute').rollback(model, key);
},
});

How do I deprecate a feature in my addon?

I am writing an Ember.js Addon, and I need to deprecate a feature. Can I use the same deprecation system that Ember uses?
I want my users to be able to silence the warnings.
Ideally, I also need to be able to test that the deprecation message works under the right conditions, from within my test suite.
I'm using Ember 3.x.
An addon can use the same style of deprecation warnings as Ember uses, through the deprecate method:
import { deprecate } from '#ember/application/deprecations';
deprecate takes three arguments: the string as a message, a boolean test where falsey means the deprecation will be shown, and an options object with more information to be displayed.
For example:
import { deprecate } from '#ember/application/deprecations';
// ...
deprecate(
"message about your addon that mentions the addon by name",
false,
{
id: 'send-component-hash',
until: '2.0.0',
url: 'some url goes here'
}
);
// ...
The message in the console will look something like this:
Testing a deprecation can be done with a library like ember-qunit-assert. Once it is installed, expectDeprecation will be available on assert if you are already using qunit in your tests:
assert.expectDeprecation(/expected deprecation message/);

Ember errors not populated in model with RESTAdapter in Ember 2.4.5 and Ember DATA 2.4.0

I'm trying to handle server errors in an Ember application.
I'm running the following code in ember app:
customization.save().catch(function (error) {
console.log(error);
console.log(customization.get('errors'));
console.log(customization.get('errors.length'));
});
And my server is answering 422 status with the following json in payload:
{
"errors":[
{
"code":"app.customization.validationError.duplicateCustomizationName",
"detail":"a customization with same name already exists",
"source":{
"pointer":"customization/name"
}
}
]
}
The error is an InvalidError, but customization.get('errors.length') is always 0.
I'm using a DS.RESTAdapter along with DS.RESTSerializer in Ember 2.4.5 with Ember DATA 2.4.0.
What am I missing ?
Thanks
Ok, I finally figured it out. The path in source.pointer MUST be in JSONAPI style even if you're not using DS.JSONAPIAdapter.
Sending this:
...
"pointer":"data/attributes/name"
...
Solves this issue.
I thought the path in pointer referred to the path of the field in the actual JSON corresponding to the model, but that's apparently wrong.

ember-cli fails on --environment=production (Uncaught Error: Could not find module)

I am using ember-cli and have a problem with selecting the production environment. Specifically, everything works when I run ember serve --environment=development and I get a blank page when I run ember serve --environment=production. In the console, I see:
Uncaught TypeError: undefined is not a function
Uncaught Error: Could not find module simple-auth/authenticators/base
All other things are equal, and all dependencies are up to date. I'm a total noob so I don't even know where to begin on how to debug: is it ember? ember-cli? broccoli? Any help would be appreciated.
I had exact the same problem, and James_1x0 is correct, it is an broccoli issue.
After debugging it occurs, that the "undefined" error apears on "Ember.handlebars.compile" which lead to other research.
It seems, that in production envrironment "handlebars.js" is replaced by "handlebars.runtime.js" in the ember-cli build process, which seem to be a problem for broccoli at this time.
Other devs had the same problem but with other libraries as well:
https://github.com/stefanpenner/ember-cli/pull/675#issuecomment-47431195
Here the solution was to add:
var index = app.legacyFilesToAppend.indexOf('bower_components/handlebars/handlebars.runtime.js');
if(index) {
app.legacyFilesToAppend[index] = 'bower_components/handlebars/handlebars.js';
}
into your Brocfile.js to replace the "handlebars.runtime.js" with the "handlebars.js".
This also fixed the problem for me.
It sure has the drawback that the whole handlebars file is deployed but its a workarround for now, until the problem is fixed.
Solution is mentioned on Ember CLI website:
This is somewhat non-standard and discouraged, but suppose that due to a requirement in your application that you need to use the full version of Handlebars even in the production environment.
Basically, you can pass vendorFiles option to your EmberApp instance which will force CLI to include full version of Handlebars.
Example of explicitly requiring handlebars.js , in Brocfile.js:
var app = new EmberApp({
vendorFiles: {
'handlebars.js': {
production: 'bower_components/handlebars/handlebars.js'
}
}
});
This is recommended way of solving this issue(discussion on GitHub).

RaphaelJs and RequireJs Not Working Togther

I am trying to load Raphaeljs using Requirejs. I tried this solution here:
https://github.com/DmitryBaranovskiy/raphael/pull/540
but when I load it I get:
Uncaught TypeError: Cannot call method 'on' of undefined
I looking more into it I saw that eve is undefined. Anyone have any ideas to get this to work with requirejs?
You can clone Raphael and update the submodules as Dmitry describes here, then for RequireJS, do this:
paths: {
"eve": "libs/raphael/eve/eve",
"raphael": "libs/raphael/raphael"
},
shim: {
'eve': {
exports: "eve"
},
'raphael': {
deps: ["eve"],
exports: "Raphael"
}
}
The just use "raphael" as a dependency when needed.
I encountered the same problem few weeks ago, but I was using JamJS, which is a front end package manager that uses Require.JS and manages require.config.js for you.
This might not solve your problem since I used JamJS, but for whatever is worth here's how I solved it: I created a package for RaphaelJS - using pmcelhaney's fork and also for Eve. You can get the packages from
Eve http://jamjs.org/packages/#/details/eve
Raphael http://jamjs.org/packages/#/details/raphael-amd