How to change the URL/route from within an observer - ember.js

How can I force the application to change the URL/route when something happens that is triggered by an observer in a controller?

You use transitionToRoute:
// controllers/item.js
export default Ember.Controller.extend({
myObserver: function() {
if(this.get('someProperty')) {
this.transitionToRoute('someOtherRoute');
}
}.observes('someProperty')
});

Related

Angular2 Unit test Service that Emit value at Constructor Time

Writing a unit test for a component, that uses a Service with an emit inside the constructor, like this:
#Injectable()
export class Service1 {
public onService1Done: EventEmitter<any> = new EventEmitter();
public constructor(...) {
this.onService1Done.emit(value);
}
}
I notice that, according to what i have in the component.spec.ts:
beforeEachProviders(() => {
return [
provide(Service1, { useClass: MockService1 }),
Component1
];
});
it("check that XXX", inject(
[Service1, Component1], (service1: Service1, component1: Component1) => {
service1.onService1Done.subscribe({ next: () => DoSomething() });
expect(DoSomething()).toEqual(IsDone);
}));
});
}
The constructor of Service1, and so the emit, will be called before i could make the subscribe, inside the test;
there is a way to avoid this ?? to make the subscribe before the Constructor ?
As always, thanks in advance.
I don't see how anything could subscribe in any way to get this event when the service instance is created by DI.
Just don't emit it in the constructor or at least use some setTimeout(...) than at least synchronically executing code has a chance to subscribe if you must.

emberjs action context is bound to the child component view instead of the component

I'm trying to pass an action up from a child component with sendAction. My action executes on the parent component as expected, however, this refers to the context of the child's view object instead.
See below for the components and component templates:
Parent component Template
// templates/components/parent.hbs
<div class="parent">
{{child name="Stewie" select="selectChild"}}
{{child name="Molly" select="selectChild"}}
</div>
{{yield}}
Child component Template
// templates/components/child.hbs
<div class="child" {{action "handleAction" on="click"}}>
name: {{name}}
</div>
{{yield}}
Child component
// components/child.js
import Ember from 'ember';
export default Ember.Component.extend({
selected: false,
actions: {
handleAction: function() {
this.set('selected', !this.get('selected'));
this.sendAction('select', this);
}
}
});
Parent component
// components/parent.js
import Ember from 'ember';
export default Ember.Component.extend({
selectedChildren: [],
actions: {
selectChild: function(child) {
// oops! this is bound to the child's view isntead of this parent component
var selectedChildren = this.get('selectedChildren');
// undefined
selectedChildren.pushObject(child);
// oops! cannot call pushObject of undefined
}
}
});
Any suggestions?
You could try
handleAction: function() {
// ...
this.sendAction('select', this.get('name')); // this.get('name') instead of this
}
In your code this.sendAction('select', this) means passing Component Object to parent component, so next behavior looks strange.

Calling a "base-class" method from an extended object

Let's say I have this:
App.ControllerMixin = Ember.Mixin.create({
setupController : function (entry) {
...
}
});
App.BaseEditController = Ember.ObjectController.extend(App.ControllerMixin, {
startEditing: function () {
...
this.setupController(entry);
},
});
App.ServicesEditController = App.BaseEditController.extend(App.ServicesMixin, {
setupController : function (entry) {
}
});
How can I call ControllerMixin.setupController from ServicesEditController.setupController?
You can call methods from super classes with this._super(). It is generally a good idea to add this call to each method you are overriding.
App.ServicesEditController = App.BaseEditController.extend(App.ServicesMixin, {
setupController : function (entry) {
this._super(entry);
}
});
Extending on my advise to add this call each overridden method, this is an example of a Mixin for a View. If your Mixin overrides didInsertElement, you should always add a call to this._super(). This ensures that "all" didInsertElement implementations get called, if multiple Mixins are applied.
App.SomeViewMixin = Ember.Mixin.create({
didInsertElement : function(){
this._super();
// ... perform your logic
}
});

Call a function inside a controller from observer in Ember

I have a controller like this
App.TestController = Ember.ArrayController.extend({
navigation:[],
somefunc:function(){
//do something
}
});
and have an observer for
globalvars = Ember.Object.create({
page : 1,
});
globalvars.addObserver('page', function() {
this.get('controller.controllers.Test').somefunc();
});
the problem is that i can't call the function inside the controller.
As i already mentioned in my comment, here a disclaimer:
You should explain in more detail, what you are trying to accomplish.
You are trying to access the controller in a strange way.
But here is an approach if you absolutely have to do it this way:
var App = Ember.Application.create({});
// put the global vars into the App object instead of polluting the global namespace
App.globalvars = Ember.Object.create({
page : 1,
});
Instead of putting the observer in the globalVars object, i would declare the observer in the controller:
App.TestController = Ember.ArrayController.extend({
navigation:[],
somefunc:function(){
//do something
},
globalVarsPageObserver : function(){
this.somefunc();
}.observes("App.globalvars.page")
});

How to know whether a method is a call made by me thgh code or its from observer

I have a method in a view just like following.
testMethod : function() {
//run code
}.observes('property1')
This method can either be trigerred directly by calling or triggered by the property1 observer. Is it possible to know inside the method, which way the call is getting triggered. Thanks
When observer is called, it receives 2 arguments: the controller object, and the observed property which has changed and triggered the observer.
So you can check it like this:
testMethod : function() {
if(arguments.length === 2 && arguments[1] === 'property1'){
// you're triggered by property observer
} else {
// triggered directly
}
}.observes('property1')
This, of course, can be spoofed by caller..
I have stumbled upon this myself and have found no way to do so. I ended up doing something like this:
testMethod : function() {
//run code
},
propertyObserver : function(){
this.testMethod();
}.observes('property1')