Ember.js Send action from controller to component - javascript

I'm writing an Ember App with jQuery Datatables. I want to send the action from the controller to refresh the table, I've used Ember Component Inbound Actions. Here is my Code:
import Ember from 'ember';
import InboundActions from 'ember-component-inbound-actions/inbound-actions';
export default Ember.Component.extend(InboundActions,{
init() {
this._super(...arguments);
},
didInsertElement() {
var table = this.$('#example').DataTable({
var _this=this;
})
},
actions: {
check: function() {
this.table.ajax.reload( null, false );
}
},
});
The result is:
Uncaught TypeError: Cannot read property 'ajax' of undefined
How to properly use this action to reload the datatables?

Related

Pass data into vuejs template

I have a Laravel application with vuejs2 support. Im using the router component in the vuejs part. How can I send data like sessions from laravel to a vuejs template. In my blade template I use <router-view ></router-view> to call the vue router component. How can I add data.
Thanks for help!
The page which you want to load using vuejs router component, add a script in the footer section of that page. And after using router push command, please refresh the whole page.
Keep a flag like: loading. At first, keep it true to view some initial message, and when you'll get axios response then make it false. Based on this flag, show the data that you get from axios response. And of course update the initially declared data after getting the axios response.
Example:
<script>
export default {
data(){
return {
loading:true,
// Others Data
}
},
methods:{
function_name (){
this.$router.push('/');
window.location.reload();
}
},
mounted() {
var _this = this;
axios.get('/data').then(function (response) {
//others data update
_this.loading=false;
});
}
}
</script>
You can use axios to make a get request to your laravel app.
Example method:
data() {
return {
data: ''
}
},
methods: {
getData: function () {
axios.get("/data")
.then((response) => {
this.data = response.data;
}, (error) => {
})
}
},
Note that you need to import axios in order to work:
import axios form 'axios'
Then you need to handle the request on the server side

How to preform a component action rather than a route action in ember-file-upload

I am using the package
https://github.com/tim-evans/ember-file-upload
In their example, they call a route action to upload an image
onfileadd=(route-action "uploadImage")}}
However I would like to instead call a component action
I tried doing
onfileadd="uploadImage"}}
and added the action in component:
uploadImage: function (file) {
console.log(file);
let self = this;
RSVP.cast(Ember.$.get(ENV.APP.API_HOST + "/v1/teams/signed_url/")).then(function (response) {
return file.upload(response.url, {
data: response.credentials
});
}).then(function (response) {
self.set('url', response.headers.Location);
});
},
But I got the error:
Uncaught TypeError: Cannot read property 'uploadImage' of undefined
The action works as expected if I move it to route, but I need to update the correct properties in the component (that do not exist in the route)
Any idea what I can do to change that to a component function ?
You should use the action helper:
onfileadd=(action "uploadImage")}}
Also make sure that uploadImage is within the actions hash in your component:
export default Ember.Component.extend({
// ...
actions: {
uploadImage() { // <-- make sure this is inside the actions hash
// ...
}
}
})

Ember js service and filterBy

i have a service to manage all the errors and alerts in my app. and the code looks like this
Service
import Ember from 'ember';
export default Ember.Service.extend({
messages: null,
init() {
this._super(...arguments);
this.set('messages', []);
},
add: function (severity, msg, messageType) {
if (severity === 'error') {severity = 'danger';}
var msgObject ={
severity: severity,
messageType: messageType,
msg: msg,
msgId: new Date()
};
this.get('messages').pushObject(msgObject);
},
remove(msgId) {
this.get('messages').removeObject(msgId);
},
empty() {
this.get('messages').clear();
}
});
Component
import Ember from 'ember';
export default Ember.Component.extend({
messageType:'global',
messageHandler: Ember.inject.service(),
messages: function(){
return this.get('messageHandler.messages').filterBy('messageType',this.get('messageType'));
}.property('messageHandler.messages'),
actions : {
dismissAllAlerts: function(){
this.get('messageHandler').empty();
},
dismissAlert: function(msgId){
this.get('messageHandler').remove(msgId);
}
}
});
Initializer
export function initialize(container, application) {
application.inject('component', 'messageHandler', 'service:message-handler');
}
export default {
name: 'message-handler',
initialize : initialize
};
Template
import Ember from 'ember';
export default Ember.Component.extend({
messageType:'global',
messageHandler: Ember.inject.service(),
messages: function(){
return this.get('messageHandler.messages');
}.property('messageHandler.messages'),
actions : {
dismissAllAlerts: function(){
this.get('messageHandler').empty();
},
dismissAlert: function(msgId){
this.get('messageHandler').remove(msgId);
}
}
});
and whenever there is an error i will add it like this
this.get('messageHandler').add('error',"Unable to get ossoi details","global");
my problem is the filterBy in the component is not working. if i remove the filterBy() it works and i can see the error in the template. am kinda new to ember so if anyone can help me figure out what am missing here or if there is a better way of doing this please let me know
filterBy usage is good and it should be working well. but messages computed property will not be recomputed whenever you add/remove item from messageHandler.messages.
messages: Ember.computed('messageHandler.messages.[]', function() {
return this.get('messageHandler.messages').filterBy('messageType', this.get('messageType'));
}),
In the above code I used messageHandler.messages.[] as dependant key for the messages computed property so that it will be called for add/remove items.
Refer:https://guides.emberjs.com/v2.13.0/object-model/computed-properties-and-aggregate-data/
Computed properties dependent on an array using the [] key will only
update if items are added to or removed from the array, or if the
array property is set to a different array.

Ember 2.4 - get current user using a service and simple auth after login

I have the following problem with getting the current user using an instance initializer, a service and ember-simple-auth library.
More specifically, I have managed to get all the attributes of my service "user" but only when I refresh the page after login.
I would like the promise that my service returns to be immediately accessible right after login.
My code snippets are available below:
app/instance-initializers/current-user.js
export function initialize(appInstance) {
appInstance.inject('route', 'account', 'service:account');
appInstance.inject('controller', 'account', 'service:account');
appInstance.inject('template', 'account', 'service:account');
}
export default {
name: 'account',
initialize: initialize
};
app/services/account.js
import Ember from 'ember';
export default Ember.Service.extend({
session: Ember.inject.service('session'),
store: Ember.inject.service('store'),
loadCurrentUser() {
const accountId = this.get('session.data.authenticated.auth_token');
console.log("This is my account", accountId);
if (!Ember.isEmpty(accountId)) {
this.get('store').findRecord('profile', accountId).then((profile) => {
this.set('user', profile);
console.log("account_group",this.get('user.user_group'));
console.log("account_username",this.get('user.username'));
});
}
return this.get('user')
}
});
Then I call the loadCurrentUser function in my application route:
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin,{
beforeModel(){
console.log("This is my currentUser", this.get("account").loadCurrentUser());
},
});
And finally in my template I can access the username of my user like this:
Logged in as: {{account.user.username}}
but only when I refresh my page.
I assume that I call my function "loadCurrentUser()" in the wrong place but I can't find anywhere a proper solution.
Thanks in advance.
I think you should call loadCurrentUser() when the authenticator resolves the promise. Something like:
that.get('session').authenticate('authenticator:xxxx',{}).then(() => {
this.get("account").loadCurrentUser();
});

Recompute arrangedContent

I'm trying to reload a model and recompute arrangedContent. The model appears to be reloading but arrangedContent is not being recomputed. Sorting data is fine, it's adding and removing data that's causing the issue.
reloadModelData: function () {
this.get('target.router').refresh();
}
My template looks like:
{{#each project in arrangedContent}}
<tr>
<td>{{project.name}}</td>
...
</tr>
{{/each}}
Edit:
routes/projects/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function () {
return this.store.findAll('project');
}
});
controllers/projects/index.js
import Ember from 'ember';
export default Ember.Controller.extend(Ember.SortableMixin, {
queryParams: ['sortProperties', 'sortAscending'],
sortProperties: ['name'],
actions: {
...
reloadModelData: function () {
this.get('target.router').refresh();
}
}
});
A button is what is triggering reloadModelData
<button {{action 'reloadModelData'}}>Reload</button>
Your model hook is not being executed in your action. Why? Becouse you are executing #refresh() on targer.router, which is not a current route, but the Router.
So, how can you refresh the model?
There is a convention called data-down-action-up. It supports sending actions up, to the objects that are, let's say, parents for the data to change. Possible solution would be to let your reloadModelData bubble up to the route and handle this action in the route. Then, in that action you could fetch the data again and set them on the controller:
# controller code
reloadModelData: function() {
return true;
}
And in route:
# route code
reloadModelData: function() {
this.store.find('project').then((function(_this) {
return function(projects) {
_this.get('controller').set('model', projects);
};
})(this));
}
If the result from the find will be different than it was, the model related computed properties will for sure recompute.
Here is a working demo in JSBin that compares your and mine solution.

Categories