Closed some1awesome closed 4 years ago
@some1awesome If you have a look into the code-examples, they also use the definitions from mobx and not mobx-angular
import { observable, computed, action, autorun, toJS } from 'mobx';
I'm still new to mobx and built a app with using only mobx. Just for the directives I am importing and using the mobx-angular things. Why it's not working in your case when you use mobx instead of mobx-angular? I did not understand the issue you get.
@some1awesome If you have a look into the code-examples, they also use the definitions from mobx and not mobx-angular
import { observable, computed, action, autorun, toJS } from 'mobx';
I'm still new to mobx and built a app with using only mobx. Just for the directives I am importing and using the mobx-angular things. Why it's not working in your case when you use mobx instead of mobx-angular? I did not understand the issue you get.
I have to import observable from 'mobx-angular' because i am using it inside a component. Inside a component importing directly from 'mobx' will fail when running an aot build. The solution I found online for that problem was to import from 'mobx-angular' instead, but when I do that I don't get access to some of the features of observable like shallow.
@some1awesome This is weird. I deploy my whole App with AOT too and don‘t have issues like this. So you mean you are using the @observable in a component, which is not part of a @injectable and causes the issue? I can try it out if it applies to your issue. I am using for example the autorun inside a component and imported it from mobx without any problem.
@some1awesome I could reproduce the issue you have. With the annotation it's not working. But the question is, what you try to reach? Do you like to have a reaction inside your component, when something changes? this can be made without the @observable annotation. Have a look to the documentation here: https://mobx.js.org/refguide/reaction.html So instead using the annotation, you create a variable with type observable (but the mobx one, not rxjs one) and then you can react to it with a reaction or an autorun. I just tested it out and it worked. But I don't know your use case.
the property in the component
observableTest = observable({ test: 'juppi' });
a function called by a button click
testit() { this.observableTest.test = Math.random().toString(); }
the reaction with an autorun
autorun( () => console.log(this.observableTest.test) );
So after every click the autorun was kicked and printed out the new value. In your case it would be
observableTest = observable.shallow(xxx);
@some1awesome, yes, there are restrictions in the components because of AOT https://github.com/mobxjs/mobx-angular#aot In the services is not this restriction and in our project, we made a workaround through the local injectable service-state. for example
import { observable, action } from "mobx";
class AppState {
@observable.shallow items = [];
@action add() {
this.items.push('value');
}
}
----
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
providers: [AppState]
})
export class AppComponent {
constructor(public state: AppState){
}
}
Need to assign all other properties from MobX observable/action/computed to the proxied ones exported from here: https://github.com/mobxjs/mobx-angular/blob/f537511510730f959f680c9594009fb394724fcc/lib/mobx-angular.ts#L29
Anybody wants to make a PR?
@adamkleingit, it will be very useful functionality and I want to make a PR, but don't know how to realize it. Can you give some sample code?
I would try to do something like this:
Object.assign(action, mobxAction)
Object.assign(computed, mobxComputed)
etc.
But it might not work because of binding, so need to check.
Would be very much appreciated
@mweststrate do you know of the top of your head will that work (for observable/action/computed)?
import {action as mobxAction} from 'mobx';
export function action(...args) {
return mobxAction(...args);
}
Object.assign(action, mobxAction);
Does any of the modifiers of observable/action/computed use 'this' inside? Or are they already bound?
Thanks
I pushed to master, but still not published. @some1awesome can you use the version from master and try it?
@adamkleingit, if I just use an Object.assign typescript compilator returns error to decorators @observable.shallow, ...
It is correct to add decorator interfaces from mobx?
function observableInternal(...args) {
return (mobxObservable as any)(...args);
}
export const observable: IObservableFactory & IObservableFactories & {
enhancer: IEnhancer<any>;
} = Object.assign(observableInternal, mobxObservable) as any;
@ildarnm I ended up using typeof. Published 3.1.0
If you import observable from mobx-angular instead of mobx you lose some of the available properties. For my specific use case I want to make a shallow observable.
When using mobx i can do the following:
@observable.shallow rows = [];
But when I try to import it through mobx-angular (which I need to do because i am doing this inside a component or it will fail in aot builds) then it says: Property 'shallow' does not exist on type '(...args: any[]) => any'.
I made a stack blitz that has the error in it: https://stackblitz.com/edit/angular-2xjhvq?file=app/app.service.ts. I think something is just wrong with the typings.