I have a Sinatra-based server which provides RESTful API for the service I'm working on. On my development machine in runs on localhost:9393.
At the same time my client application (built with ember.js) which uses ember-auth for user authentication runs on another port: localhost:9000.
Previously I set up both server and client on the same host:port and returned client app as static files. Authentication worked pretty well. According to the official docs on SignIn I get POST request on the route I provided (/signin). But now I recieve OPTIONS request with no params whatsoever.
Some code from client (client is generated via Yeoman's ember-generator):
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Ember Starter Kit</title>
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/bootstrap.css">
<link rel="stylesheet" href="styles/bootstrap-responsive.css">
<link rel="stylesheet" href="styles/style.css">
<!-- endbuild -->
</head>
<body>
<!-- build:js scripts/components.js -->
<script src="components/jquery/jquery.js"></script>
<script src="components/handlebars/handlebars.runtime.js"></script>
<script src="components/ember/ember.js"></script>
<script src="components/ember-data/ember-data-latest.js"></script>
<script src="components/ember-auth/ember-auth.js"></script>
<!-- endbuild -->
<!-- build:js scripts/main.js -->
<script src="scripts/app.js"></script>
<script src="scripts/models/user.js"></script>
<script src="scripts/views/auth.js"></script>
<!-- endbuild -->
<!-- build:js(.tmp) scripts/templates.js -->
<script src="scripts/compiled-templates.js"></script>
<!-- endbuild -->
</body>
</html>
app.js
var App = window.App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter:'DS.RESTAdapter'
});
App.Router.map(function() {
// I have no routes so far,
// as I don't need them to test authentication itself
});
App.Auth = Ember.Auth.create({
signInEndPoint: '/signin',
signOutEndPoint: '/signout',
tokenKey: 'auth_token',
baseUrl: 'http://localhost:9393',
tokenIdKey: 'user_id',
userModel: 'App.User',
sessionAdapter: 'cookie',
modules: [
'emberData', 'rememberable'
],
rememberable: {
tokenKey: 'remember_token',
period: 7,
autoRecall: true
}
});
user.js
App.User = DS.Model.extend({
email: DS.attr('string'),
param: DS.attr('string')
});
auth.js
App.AuthView = Ember.View.extend({
templateName: 'auth'
});
App.AuthSignInView = Ember.View.extend({
templateName: 'signin',
email: null,
password: null,
remember: true,
submit: function(event, view){
event.preventDefault();
event.stopPropagation();
App.Auth.signIn({
data:{
email: this.get('email'),
password: this.get('password'),
remember: this.get('remember')
}
})
}
});
App.AuthSignOutView = Ember.View.extend({
templateName: 'signout',
submit: function(event, view){
event.preventDefault();
event.stopPropagation();
App.Auth.signOut();
}
});
application.hbs
<div class="container">
<div class="row">
<div class="span3">
{{view App.AuthView}}
</div>
<div class="span9">
{{outlet}}
</div>
</div>
</div>
auth.hbs
{{#if App.Auth.signedIn}}
{{view App.AuthSignOutView}}
{{else}}
{{view App.AuthSignInView}}
{{/if}}
signin.hbs
<form>
<label>Email</label>
{{view Ember.TextField valueBinding="view.email"}}
<label>Password</label>
{{view Ember.TextField type='password' valueBinding="view.password"}}
{{view Ember.Checkbox checkedBinding="view.remember"}}
<label>Remember me?</label>
<hr />
<button type="submit">Sign In</button>
</form>
Your REST API and client app are served from different origins; the protocol, host and port must be identical to follow same-origin policy. Your browser is making a preflight OPTIONS request to determine if your server will allow cross-origin resource sharing (CORS) from your client domain.
To get CORS working with your Sinatra server, you might want to check out rack-cors which will allow you to add middleware for setting the requisite access control headers. Once that is set up correctly, the expected POST request will be issued following the successful OPTIONS request.
For more on CORS, here are some resources I've found useful:
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
http://remysharp.com/2011/04/21/getting-cors-working/
http://www.bennadel.com/blog/2327-Cross-Origin-Resource-Sharing-CORS-AJAX-Requests-Between-jQuery-And-Node-js.htm
Related
I'm trying to change the height of a panel in an ember .hbs file from it's controller. I've seen lots of examples, but I can't seem to get things right. Here's a jsbin I put together for it, and following that is my code. Any help will be much appreciated.
Thanks!
version: 1.13.8
node: 0.12.7
npm: 2.13.4
os: win32 x64
http://jsbin.com/kopajitili/3/edit?html,js,output
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
<script src="http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.5/ember.debug.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<div class="panel panel-primary" id="linkPanel" style="width:205px;">
<div class="panel-heading">
<h3 class="panel-title">Stuff</h3>
</div>
<div class="panel-body">
Blah blah blah...
</div>
<div>
<button style="margin: 10px;" {{action "addHeight"}}>Add Stuff</button>
</div>
</div>
</script>
</body>
</html>
Controller (JS)
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.ApplicationController = Ember.Controller.extend({
actions: {
addHeight: function() {
// My goal here is to be able to increase the height
// of the panel "#linkPanel" from an action.
// In this version, I'm just trying to see
// if I can reference the panel (I can't.)
// In the commented out lines, I was trying
// to actually change it.
// Any help and/or advice will be much appreciated.
alert(document.getElementById('#linkPanel'));
//this.set('this.document.getElementById('#linkPanel').height',"500px");
//this.set('this.document.getElementById('#linkPanel').style.height',"500px");
//this.set('document.getElementById('#linkPanel').style.height',"500px");
//this.set('document.getElementById('#linkPanel').style.width',"500px")
//this.set('document.getElementById('#linkPanel').style',"Height=500px")
}
}
});
When you call getElementById you should not prepend the # -- that is jQuery syntax. Revise it to document.getElementById('linkPanel');
Revised your JSBin:
http://jsbin.com/liwovawexu/edit?js,output
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.ApplicationController = Ember.Controller.extend({
actions: {
addHeight: function() {
document.getElementById('linkPanel').style.height = "500px";
}
}
});
Nothing handled the action error occurs for the following code. How to resolve this?
I have created a view, an object for my sample app using ember. But the action part is not working.
How to bind an action to a view?
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
</head>
<body>
<script type="text/x-handlebars">
<ul class="mod-choosable-list">
{{view Ember.CollectionView
contentBinding="App.teachersController"
itemViewClass="App.TeacherView"
tagName="div"
}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="teacher-view">
<div {{action 'refresh'}}><b>{{view.content.name}}</b></div>
</script>
<script src="js/libs/jquery-v1.11.1.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember-v1.6.1.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
JS:
App = Ember.Application.create({});
App.Teacher = Ember.ObjectController.extend({
id: null,
name: null,
students: null,
actions: {
refresh: function(){
alert("refresh");
}
}
});
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view'
});
App.set('teachersController', Ember.ArrayController.create({
content: [
App.Teacher.create({id:1, name: "mr.katz", students: [2, 3]}),
App.Teacher.create({id:2, name: "mr.dale", students: [1]})
]
}));
When you trigger the action refresh, ember will look for the action in the controller. Since you have not specified a controller for the view, the controller for the application template will be used which is App.ApplicationController.
You can use the following code and your action will trigger.
App.ApplicationController = Em.Controller.extend({
actions: {
refresh: function(){
alert("refresh");
}
}
});
You can specify the actions in the view too. In that case you will need to specify the target for the action. This will tell ember where to look for the action handler.
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view',
actions: {
refresh: function(){
alert("refresh");
}
}
});
<div {{action 'refresh' target="view"}}><b>{{view.content.name}}</b></div>
You can specify a controller for view on its init event.
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view',
setup:function() {
this.set('controller', App.Teacher.create());
}.on('init')
});
I have written a html with a div.
I have two hbs files. I rendered one as partial and other as normal. I am not able to invoke action on the templates. I am getting missing helper error.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="holder">
</div>
<script src="js/libs/jquery-v1.11.1.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember-v1.6.1.js"></script>
<script src="js/libs/ember-data.js"></script>
<script src="js/app.js"></script>
</body>
</html>
JS:
var data={title: "My New Post", body: "This is my first post!"};
function getTemplate(templateName,hbsPath,type){
$.ajax({
url: hbsPath, //ex. js/templates/mytemplate.handlebars
cache: true
}).done(function (src) {
if (type === "partial") {
Handlebars.registerPartial(templateName, $(src).html());
} else {
template = Handlebars.compile($(src).html());
temp=template(data);
$("#holder").append(temp);
}
});
}
getTemplate("dummy","/Test/templates/dummy.hbs","partial");
getTemplate("dummy","/Test/templates/application.hbs");
App = Ember.Application.create({});
App.Router.map(function(){
this.resource('dummy');
});
App.ApplicationController=Ember.ObjectController.extend({
needs:['dummy'],
actions:{
refresh: function(){
alert("application template refresh");
}
}
});
App.DummyController=Ember.ObjectController.extend({
actions:{
refresh: function(){
alert("dummy template refresh");
}
}
});
HBS:
application.hbs:
<script id="application" type="text/x-handlebars-template">
{{> dummy}}
</script>
dummy.hbs:
<script type="text/x-handlebars" data-template-name='dummy'>
<div {{action 'refresh' target="controllers.dummy"}}>
Refresh
</div>
<div {{action 'refresh'}}>
Refresh
</div>
</script>
The code in ur demo and the code in question are different. Here is a fixed demo based on the code in ur question.
Fixing the demo u provide may need you to include the vanilla handlebars library as ember is now using HTMLBars which is built on top of handlebars but a bit different.
Em.Handlebars.compile is now actually using HTMLBars compile method. You can see here.
You may need to use something like https://github.com/rwjblue/broccoli-ember-inline-template-compiler
I am just starting with the bare-bones starter kit, trying to do something very basic.
In my end result app, there will be a list of categories and subcategories that serve as the nav for the app. My solution being an Ember novice, and just to get something working, was to start with the tutorial by Tom Dale and try moving from there. So, I set up a variable to hold some dummy models to use just to get something on the screen.
When I try to run the app, I get the error Uncaught TypeError: Cannot set property 'dataSourceBinding' of undefined
EDIT--
I have tried moving the declaration of the categories variable to the top of the app.js file, but still get the same error.
My question is really two questions:
What am I missing/doing incorrectly?
I realize that ultimately setting up the app with the categories as a model on the index action is probably not the best approach. This list needs to be dynamic as it will be configurable by users. Is there a better way to have this dynamic nav included in the main template?
app.js:
MSSWApp = Ember.Application.create();
MSSWApp.Router.map(function() {
this.resource('categories', function() {
this.resource('category', { path: ':category_id' });
});
});
MSSWApp.IndexRoute = Ember.Route.extend({
model: function() {
return categories;
}
});
var categories = [{
id: 1,
title: "Auto & Mechanical"
}, {
id: 2,
title: "Beauty & Fashion"
}, {
id: 3,
title: "Careers & Education"
}];
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="initial-scale=1.0">
<title>Test Ember Model on Index</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars">
<h1>Categories</h1>
<ul>
{{#each in model}}
<li>
<h2>
{{#link-to 'category' this}}
{{title}}
{{/link-to}}
</h2>
<ul>
<li>
Sub 1-1
</li>
<li>
Sub 1-2
</li>
<li>
Sub 1-3
</li>
</ul>
</li>
{{/each}}
</ul>
{{outlet}}
</script>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.5.1.js"></script>
<script src="js/app.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>
Turns out that the template needs a name, otherwise Ember assumes that's the application template.
setting up the script tag like this:
<script type="text/x-handlebars" data-template-name="index">
did the trick
I'm creating a simple Ember JS app based loosely on the Beginner's Guide on the website. However, I can't seem to get anything to render on the page. When I check the Ember Inspector my routes are all present and I don't see any errors so it's not immediately clear where the problem is.
Here is the html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Coin</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body>
<script type="text/x-handlebars">
<div>Hello</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="accounts">
<div>accounts</div>
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
{{#each}}
<li>account link {{#link-to 'account' this}}{{name}}{{/link-to}}</li>
{{/each}}
</ul>
</div>
<div class="col-md-10">
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="account">
<ul>
{{#each}}
<li>{{comment}}</li>
{{/each}}
</ul>
</script>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.4.0.js"></script>
<script src="js/app.js"></script>
<script src="dist/js/bs-core.min.js"></script>
<script src="dist/js/bs-nav.min.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>
And here is my app.js file:
App = Ember.Application.create();
App.Router.map(function() {
this.resource('accounts');
this.resource('transactions', { path: ':accounts_id' });
})
App.AccountsRoute = Ember.Route.extend({
model: function() {
return accounts;
}
})
App.TransactionsRoute = Ember.Route.extend({
model: function() {
return transactions;
}
})
var accounts = [{
id: 1,
name: 'Account 1',
}, {
id: 2,
name: 'Account 2'
}];
var transactions = [{
id: 1,
id_account: 1,
amount: 12,
comment: 'blah'
}, {
id: 2,
id_account: 1,
amount: 5,
comment: 'blah2'
}, {
id: 3,
id_account: 2,
amount: 98,
comment: 'blah4'
}];
The one thing that renders properly on the page is the "Hello" in the application template. Nothing shows in the {{outlet}} when I navigate to #/accounts or any of the other defined routes. And in fact, when I add #/accounts in the url even my "Hello" disappears.
Is there something obvious that I'm overlooking? I'm new to Ember so I'm sure it's something silly but I can't figure out where the problem is from the documentation.
edit: I'm using Ember v1.4.0 linked directly from the website and I have checked "Allow access to file urls" in Ember Inspector.
I made a working version of what you started in this ember jsbin
What I noticed you were doing wrong was by trying to link to a non-existing route with this {{#link-to 'account' this}}. You didn't define the account route that I notice you want to receive a parameter. However I think you want to send the id of the current item in the iteration. So you can simply do that by changing this into {{#link-to 'account' id}}.
So 2 important modifications to get to something working was to add the route and to fix the param of the link-to helper. Then I just assumed that you want to show transactions as well and fixed that as well.
Hope this helps.