set model attribute from ember uploader S3 url? - ember.js

I have got ember-uploader to upload files successfully to S3. When the image is done uploading, I would like to set the model property image_url to the returned URL, then preferably submit the form to create the record as well. How would I do that?
app/models/post.js:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
body: DS.attr('string'),
image_url: DS.attr('string')
});
app/templates/posts/new.hbs:
<div class="new-post-form">
{{input type="text" placeholder="Name" value=name}}
{{input type="text" placeholder="Message" value=body}}
{{s3-upload value=image_url}}
<button {{action 'addPost'}} class="submit">Submit</button>
</div>
app/components/s3-upload.js:
import Ember from 'ember';
import EmberUploader from 'ember-uploader';
export default EmberUploader.FileField.extend({
url: 'http://localhost:3000/sign',
filesDidChange: (function() {
var uploadUrl = this.get('url');
var files = this.get('files');
var uploader = EmberUploader.S3Uploader.create({
url: uploadUrl
});
uploader.on('didUpload', function(response) {
// S3 will return XML with url
var uploadedUrl = Ember.$(response).find('Location')[0].textContent;
uploadedUrl = decodeURIComponent(uploadedUrl); // => http://yourbucket.s3.amazonaws.com/file.png
console.log("UPLOADED ! : " + uploadedUrl);
});
if (!Ember.isEmpty(files)) {
uploader.upload(files[0]); // Uploader will send a sign request then upload to S3 }
}).observes('files')
});
As you can see I tried setting the value of my s3-uploader component to image_url, that didn't seem to do anything.

Related

ember.js and firebase - unable to sign up user

I'm trying to get a user sign up working on my ember app using firebase as the backend. I'm using the torii add-on for user authentication and am just trying to test it out. However when I try to sign up a user I get the following error: Uncaught TypeError: n.default is not a constructor
This is how my route looks at routes/index.js:
import Ember from 'ember';
import Firebase from 'firebase';
export default Ember.Route.extend({
actions: {
signUp: function(){
var controller = this.get('controller');
var firstName = controller.get('firstName');
var lastName = controller.get('lastName');
var email = controller.get('email');
var password = controller.get('password');
var ref = new Firebase("https://my-app-name.firebaseio.com");
var _this = this;
ref.createUser({
email : email,
password : password
},
function(error, userData){
if (error) {
alert(error);
} else {
_this.get('session').open('firebase', {
provider: 'password',
'email': email,
'password': password
}).then(function(){
var user = _this.store.createRecord('user', {
id: userData.uid,
firstName: firstName,
lastName: lastName
});
user.save().then(function(){
_this.transitionTo('protected');
});
});
}
});
}
}
});
My template at templates/index.hbs:
Signup here: <br>
{{input type="text" value=firstName placeholder="First Name"}}<br>
{{input type="text" value=lastName placeholder="Last Name"}}<br>
{{input type="text" value=email placeholder="Email"}}<br>
{{input type="password" value=password placeholder="Password"}}<br>
<button {{action "signUp"}}> Sign Up </button>
and my user model:
import DS from 'ember-data';
export default DS.Model.extend({
firstName: DS.attr(),
lastName: DS.attr()
});
I'm really not sure where I'm going wrong. I've pretty much followed this guide: http://vikram-s-narayan.github.io/blog/authentication-with-ember-and-firebase-part-2/, except I'm just focusing on the sign up and putting it all in the index for simplicity.
Problem was I'm using the Firebase 3.0 SDK but using code for a previous version. Moved the code into my controller and updated it to use createUserWithEmailAndPassword:
import Ember from 'ember';
export default Ember.Controller.extend({
firebaseApp: Ember.inject.service(),
actions: {
signUp() {
const auth = this.get('firebaseApp').auth();
auth.createUserWithEmailAndPassword(this.get('email'), this.get('password')).
then((userResponse) => {
const user = this.store.createRecord('user', {
id: userResponse.uid,
email: userResponse.email
});
return user.save();
});
}
}
});

Why doesn't Ember model update?

My goal is to simply update append a number to an array model. This should create a new HTML element due to the iterator I have used in the template.
My action does get called, but the model doesn't really update.
Here is my directory structure:
- app
- routes
- compare.js
- templates
- compare.hbs
- application.hbs
- app.js
- index.html
- router.js
compare.hbs:
<div id="container">
<form method="post" name="login" {{action "submit" on="submit"}}>
<p>
Member ID
</p>
<p> {{input id="member-id" type="text"}} <input type="submit" value="Search"></p>
</form>
<div id="results">
{{#each model as |result|}}
<p>{{ result }}</p>
{{/each}}
</div>
</div>
router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('compare');
});
export default Router;
compare.js
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
results.push(123);
this.get('model').push(123);
this.refresh();
}
}
});
What is the problem?
It looks like you have a few issues. You don't need results.push as that is just adding the value to the array outside of Embers knowledge. When adding to the model use pushObject as that should notify ember of the change. There is also no need to call refresh on the model.
The documentation for pushObject shows an example very similar to what you are attempting:
http://emberjs.com/api/classes/Ember.NativeArray.html#method_pushObject
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
this.model().pushObject(123);
}
}
});

Model hook throwing error. Ember

In my application users have many meals. meals belong to a user. I have it so that a user can currently post a meal by creating a record and saving it. Immediately after completing this my console threw the error:
Error: Assertion Failed: You need to pass a model name to the store's modelFor method at new Error (native)
I then wrote my model hook for getting meals, when I started to get the error:
TypeError: Cannot read property 'some' of undefined
I am not certain what is causing this. Here is my code:
User Model:
import DS from 'ember-data';
import { hasMany } from 'ember-data/relationships';
export default DS.Model.extend({
email: DS.attr('string'),
height: DS.attr('number'),
weight: DS.attr('number'),
age: DS.attr('number'),
tdee: DS.attr('number'),
gender: DS.attr('string'),
activity_level: DS.attr('number'),
meals: hasMany('meal')
});
Meal model:
import DS from 'ember-data';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default DS.Model.extend({
meal_type: DS.attr('string'),
created_at: DS.attr('date'),
user: belongsTo('user'),
// meal_items: hasMany('meal_item')
});
Meal route:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').findAll('meal');
},
actions: {
createMeal(data) {
let meal = this.get('store').createRecord('meal', data);
meal.save();
}
}
});
I am new to ember, but have a hunch it may be related to explicit inverses? An advice is appreciated. I can post more code if something needs clarification.
EDIT:
The GET request to the server successful. The meal data is in the DS.
So I pass the createMeal action down to my create-meal component:
{{create-meal meals=model createMeal="createMeal"}}
The component sends this action back up on submit:
import Ember from 'ember';
export default Ember.Component.extend({
form: {},
actions: {
submit (){
this.sendAction('createMeal', this.get('form'));
}
}
});
Here is my template for that component:
<label class="col-md-3">Create A Meal</label>
<div class="input-group col-md-8 col-centered create-meal-div">
{{input value=form.meal_type type="text" class="form-control" placeholder="Enter Meal Name" aria-describedby="basic-addon2"}}
<span class="input-group-addon" id="basic-addon2"><button type="submit" class="btn-primary" {{action "submit" form on "submit"}}> Start Adding Food</button></span>
</div>
<div class="col-md-6 food-search-div">
{{food-search}}
</div>
EDIT 2:
rails controller meal create action:
def create
# binding.pry
#meal = current_user.meals.build(meal_params)
if #meal.save
render json: #meal, status: :created, location: #meal
else
render json: #meal.errors, status: :unprocessable_entity
end
end
SOLVED:
REMOVING the user: belongsTo('user'), in my meal model go rid of the error.
I think the problem is here in this line - router
return this.get('store').findAll('meal');
Try this but it is weird it should work
model() {
return this.store.findAll('meal');
}
Inside controllers you need to use this.get('store') when you are inside route just this.store. Try that and let me know if it works. Also inside your route set the action to accept the model as param, like this
actions: {
update(model){
model.save().then( ....
This can be triggered from template like this
<form {{action 'update' model on='submit'}} autocomplete="off">
In this way you do not need to get this.store in your route - you will have a model passed and you can just go to save
Hope it helps
EDIT: also this would prevent ember cli to precompile
user: belongsTo('user'),
// meal_items: hasMany('meal_item')
so it should be without ,
user: belongsTo('user')
// meal_items: hasMany('meal_item')

Uncaught Error: No model was found for 'model'

I'm building an Ember-CLI app using the following:
DEBUG: Ember : 1.10.0
DEBUG: Ember Data : 1.0.0-beta.15
DEBUG: jQuery : 2.1.3
Using a form, I'm trying to save changes on 2 separate models.
One of the models (the user model) saves successfully, while the other (profile model) throws this error:
Uncaught Error: No model was found for 'userProfile'
Models
The two models in question are:
models/user.js
models/user/profile.js
user model:
import DS from "ember-data";
export default DS.Model.extend({
email: DS.attr('string'),
username: DS.attr('string'),
firstname: DS.attr('string'),
lastname: DS.attr('string'),
comments: DS.hasMany('comments'),
});
profile model:
import DS from "ember-data";
export default DS.Model.extend({
avatar: DS.attr('string'),
educationDegree: DS.attr('string'),
educationUniversity: DS.attr('string'),
workRole: DS.attr('string'),
workOrganisation: DS.attr('string'),
interests: DS.attr('string'),
});
Controller
import Ember from "ember";
export default Ember.Controller.extend({
saved:false,
actions: {
save:function(){
this.get('model.user').save();
this.get('model.profile').save();
this.set('saved',true);
},
},
});
Route
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function(){
var _this = this;
var currentUser = this.get('session.user');
return new Ember.RSVP.all([
_this.store.find('user', currentUser.id),
_this.store.find('user.profile', {UserId: currentUser.id}),
]).then(function(values){
return {
user: values[0],
profile: values[1].get('firstObject'),
}
});
},
});
Template
<form {{action "save" on="submit"}}>
{{input type="text" placeholder="First Name" value=model.user.firstname}}
{{input type="text" placeholder="Last Name" value=model.user.lastname}}
{{input type="email" placeholder="Email" value=model.user.email}}
{{input type="text" placeholder="Affiliation" value=model.profile.workOrganisation}}
<button type="submit" class="btn teal white-text">Save</button>
{{#if saved}}
<p class="text-valid">Save Successful.</p>
{{/if}}
</form>
This error occurs because Ember Data cannot find a model into which to insert the data coming back from the PUT ensuing from the save, which I assume looks like
{ userProfile: { ... } }
I don't know the exact rules by which Ember looks up models based on these "root keys" such as userProfile, but I doubt if it can find the profile model hiding down underneath models/user/.
In the past the following has worked for me, if you have control over the server:
{ "user/profile": { ... } }
If you can't change the server response, or this fails to work for some other reason, the simplest thing to do is to move the profile model up to the top level of the models directory and name it user-profile.js.
Another alternative is to play with modelNameFromPayloadKey:
// serializers/application.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
modelNameFromPayloadKey: function(payloadKey) {
if (payloadKey === 'userProfile') payloadKey = 'user/profile';
return this._super(payloadKey);
}
});

Trigger login modal before performing action - Ember

I'm trying to figure out how to trigger my login modal before allowing user to create something.
Did some research, found that I could use beforeModel, but I'm concerned that would prevent user from seeing the entire route? I want the route to remain visible, just want the user to be triggered a login modal if not authenticated yet.
My template:
<div class="input-group input-group-lg center-block">
{{input class="form-control" type="text" value=newListTitle action="createList" placeholder="Create a Stack"}}
</div>
My route with the action:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('list');
},
actions: {
createList: function() {
var newListTitle = this.controllerFor('lists').get('newListTitle');
//var user = this.get('session.user.displayName');
var userId = this.get('session.user.uid');
//var user = this.get('session.user');
if (Ember.isBlank(newListTitle)) { return false; }
//1
var list = this.store.createRecord('list', {
title: newListTitle,
user: userId,
});
...
Modal:
{{#modal-dialog title="modal" id="modal" action="close"}}
...
Thanks, I'd appreciate if you could point me in the right direction.