This code works (hardcoded):
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
let stars = [
{
key: "johnlennon",
logoUrl: "https://www.images.com/johnl.png",
name: "John Lennon",
alive: false
}
}
}
});
When I do this, it doesn't (from API):
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import config from '../../../../../config/environment';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
const token = this.get('session.data.authenticated.token');
return Ember.RSVP.hash({
stars: Ember.$.getJSON(Ember.$.getJSON(`${config.APP.starsAPI}/api/stars?authorizationToken=${token}`))
});
}
});
The error I receive:
jquery.js:9175 GET
http://localhost:4242/stars/948/connect/[object%20Object] 404 (Not
Found)
ember.debug.js:30291 Error while processing route:
stars.show.connect.stars.index
As you may have guessed, I need it to work from API. Why is that giving me the error?
It worked after this change:
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import config from '../../../../../config/environment';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
const token = this.get('session.data.authenticated.token');
return Ember.$.getJSON(`${config.APP.starsApi}/api/stars?authorizationToken=${token}`).then(function(retVal){
return retVal;
});
}
});
Looks like you had chained `Ember.$.getJSON() methods.
return Ember.$.getJSON(`${config.APP.starsApi}/api/stars?authorizationToken=${token}`).then(function(retVal){
return retVal;
});
This should work fine
Related
Let, I have two routes and two controllers namely login and signup
If I signup successfully then I want to perform transition to the route login with a success message as parameter,
/app/signup/controller.js
import Controller from '#ember/controller';
export default Controller.extend({
actions: {
signup: function(){
let _this = this;
let successMessage = 'successfully registered';
var credentials = this.getProperties('name','identification','password');
let list = this.store.createRecord('user', {
name: credentials.name,
email: credentials.identification,
password: credentials.password
});
list.save().then(function(){
_this.transitionToRoute('login','successMessage');
});
}
}
});
app/login/template.hbs
<body>
{{successMessage}}
</body>
/app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('login');
this.route('signup');
});
export default Router;
I think you sort of have 3 options:
Use a route param (query param or positional)
Use a service to manage login stuff, and read some computed property from the service representing your state / message from your login controller
Use a flash/toast style UI where the message lives outside of the app view/component hierarchy
Personally, for where you want to display your message, I'd go for #2, which would look like this:
// app/services/user-session.js
import Service from '#ember/service';
export default class extends Service {
successMessage = null;
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
}
// app/controllers/signup.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { action } from '#ember-decorators/object';
export default class extends Controller {
#service userSession;
#action
signup() {
this.userSession.signup(...);
this.transition...
}
}
// app/controllers/login.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { readOnly } from '#ember-decorators/object/computed';
export default class extends Controller {
#service userSession;
#readOnly('userSession.successMessage') successMessage;
}
Or, in the old syntax:
// app/services/user-session.js
import Service from '#ember/service';
export default Service.extend({
successMessage: null,
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
});
// app/controllers/signup.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
export default Controller.extend({
userSession: service(),
actions: {
signup() {
this.userSession.signup(...);
this.transition...
}
}
});
// app/controllers/login.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
import { readOnly } from '#ember/object/computed';
export default Controller.extend({
userSession: service(),
successMessage: readOnly('userSession.successMessage')
});
hope this helps
I have an ember.js toy application that I want to hook into a JSONAPI REST service for obtaining and displaying data. I can trace in my browser's developer console, that indeed, ember-data initiates the appropriate GET requests and receives proper, valid JSONAPI response bodies.
// ./app/models/person.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
birthdate: DS.attr('string')
});
// ./app/adapters/person.js
import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
pathForType() {
return "persons";
}
});
// ./app/adapters/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'http://localhost:5000'
});
// ./app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function () {
this.route('persons', function() {
this.route('show', { path: '/:person_id' });
});
});
export default Router;
// ./app/routes/persons/show.js
import Route from '#ember/routing/route';
export default Route.extend({
model(params) {
return this.get('store').findRecord('person', params.person_id);
}
});
// ./app/routes/persons/index.js
import Route from '#ember/routing/route';
export default Route.extend({
model() {
return this.get('store').findAll("person");
}
});
// ./app/routes/application.js
import Route from '#ember/routing/route';
export default Route.extend({
});
// ./app/app.js
import Application from '#ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
// ./app/resolver.js
import Resolver from 'ember-resolver';
export default Resolver;
Unfortunately, when I want to use the model in my template, I can only access the element ids, and not the data attributes like name (Remains empty when rendered).
<!-- ./app/templates/persons/index.hbs -->
{{#each model as |person index|}}
<li>
Person {{person.id}} {{index}}
{{person.name}}
{{#link-to 'persons.show' person }}
Link {{index}}
{{/link-to}}
</li>
{{/each}}
I am a bit at loss for why this happens. Am I doing something wrong?
The posted code is fine, the attributes I was missing in the templates was actually missing from the HTTP responses.
My ember version:
---------------------------
Ember : 2.10.2
Ember Data : 2.10.0
jQuery : 2.2.4
Ember Simple Auth : 1.1.0
Model Fragments : 2.3.2
---------------------------
My route code like:
import Ember from 'ember';
import RSVP from 'rsvp';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
return RSVP.hash({
orderTransactionTypes: this.store.query('transactionType', {
filter: {
category: 'order_category'
}
}),
otherTransactionTypes: this.store.query('transactionType', {
filter: {
category: 'transaction_category'
}
})
});
},
setupController(controller, model) {
controller.set('model', model);
}
})
In RSVP.hash all data come from transactionType, but they have not same query params. I use this way set model will have a problem is model. orderTransactionTypes and model.otherTransactionTypes become same data.
Whey this problem is happened? And how can I fix this problem? Thanks.
Is there a way in Ember to send cookies with the requests to the backend?
For example: if my client URL is protocol://example.com. The cookies that belong to the same domain will be in the request header when I navigate to protocol://example.com/profile. However, they do not persist in the subsequent request/s the profile route model method makes -> example to protocol://example-host/posts. How do I make those cookies persist?
/app/routes/profile.js:
import Ember from "ember";
import AuthenticatedRouteMixin from "simple-auth/mixins/authenticated-route-mixin";
export default Ember.Route.extend({
model() {
return this.store.findAll("post");
},
renderTemplate() {
this.render("header", {
outlet: "header"
});
this.render("profile");
}
});
/app/adapters/application:
import Ember from "ember";
import DS from "ember-data";
export default DS.RESTAdapter.extend({
host: 'http://example-host.com',
corsWithCredentials: true,
crossDomain: true,
xhrFields: { withCredentials: true }
});
This works in my production app. Code in app/adapters/application.js:
import Ember from 'ember';
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
export default DS.RESTAdapter.extend({
ajax(url, method, hash) {
hash = hash || {};
hash.crossDomain = true;
hash.xhrFields = {
withCredentials: true
};
return this._super(url, method, hash);
}
})
You can also set individual header values to be sent with each ember-data request. Useful if you need to pass an API key with all your requests.
In your adapter (app/adapters/application.js):
import DS from 'ember-data';
import { get } from '#ember/object';
import { computed } from '#ember/object';
export default DS.RESTAdapter.extend({
headers: computed(function() {
return {
'API_KEY': get(document.cookie.match(/apiKey\=([^;]*)/), '1'),
'ANOTHER_HEADER': 'Some header value'
};
}).volatile()
});
Is there a more elegant way to prevent unauthorized access to an admin-only route than writing this in all of my admin routes?
export default Ember.Route.extend(AuthenticatedRouteMixin, {
beforeModel: function(){
if(!this.get('session.secure.admin')) this.transitionTo("dashboard");
}
});
Perhaps it's possible to extend AuthenticatedRouteMixin itself to make this kind of check?
Thanks!
Why not just make the mixin?
import Ember from 'ember';
import AuthenticatedRouteMixin from 'wherever/it/is'.
const { Mixin } = Ember;
export default Mixin.create(AuthenticatedRouteMixin, {
beforeModel(){
if(!this.get('session.secure.admin')) {
this.transitionTo("dashboard");
}
}
})
And then import it in your routes:
import Ember from 'ember';
import AdminCheckMixin from 'yourApp/mixins/routes/admin-check';
const { Route } = Ember;
export default Route.extend(AdminCheckMixin);