Using Dependency Injected Fields in Ember Controllers - javascript

How do I use a dependency injected field in another field within the ember controller in 2.x Ember?
For instance, I have
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
user: this.get('session').username
How is user able to access the lazily computed values of session?
I noticed that the case above doesn't work as I believe the value of session has been computed yet?
I could use a computed property but I use user as a value in input and I am merely setting a base value.

Not sure if I understood your question correctly, but it seems like you could use computed property function (I usually handle it this way when it comes to DI):
user: Ember.computed.oneWay('session.username')
Or simpler, alias:
user: Ember.computed.alias('session.username')

Related

Using a computed property from a vuex getter in a module

I have this demo: https://codesandbox.io/s/runtime-bash-61mfo
I´m working with the rootState all the time, but I need find the actual element across all the elements with it´s id, so I created parentItem for this.
There are any way to access to parentItem in the myProperties getter?? I need this to later use mutations and actions across this getter to change the rootState parent item.
If I use the Method-Style Access I have to put it in the alert.js store and I cannot have access to the parentItem computed property…
Besides, in every other getter/action/mutation should send the ID to pass again to the correct getter to obtain the parentItem, when I already have the id thanks to the props…
Any idea how can accomplish this?
I can change all the structure if it´s required, but I don´t find any better way to structure the data...

Use a Plugin (VeeValidate) in Store.js

I'm working with Vuex and added vee-validate (found here). I'm using a store object and from one of its actions, I want to be able to add custom errors to the errors collection based on a server response. Is it possible to access vee-validate's global errors (ErrorBag) collection that's used as an attribute typically?
According to this, I should be able to add to the errors object, but this isn't the same when I'm in my store object obviously.
For example:
<span id="error-message" v-if="errors.has('phone')">error message</span>
I'm hoping there's a way to access that errors collection. Is there a way I need to import VeeValidate to get access to what I need? Is it globally available somehow?
I would suggest that errors raised in the action be added to the store, and accessed in the component from a computed property.
That follows the one-way-data-flow principle, and since computed's are reactive should give an opportunity for the view to update asynchronously.
Perhaps:
<span id="error-message" v-if="allErrors.has('phone')">error message</span>
computed: {
allErrors() {
return this.$validator.errors
.concat( this.$store.state.asyncErrors )
}
Details need to be fleshed out.

Proper way to bind to data object in Angular 2 service?

I am building an angular 2 application. The documentation has changed quite a bit since the released which has caused confusion. The best I can do is explain what I am trying to do (Which was easy in Angular 1) and hope someone can help me out.
I have created a login service using JWT's.
Once login is successful, I return a user object.
I have a loginComponent ( binds data to template ) and loginService ( which handles the https calls )
I have a userService which maintains the user object.
I have a userComponent which renders the user data.
The problem is, once the user has logged in, I am unclear on the best approach for letting the userService retrieve the new data in an object called "user", then the userComponent update its user object on the template. This was easy in angular 1 simply by putting a watcher on the userService.user object.
I tried Inputs and Outputs to no avail, eventEmitters, Observables and getters and setters. The getters and setters work, but force me to store everything in a "val()"
Can someone please tell me the best way to achieve this?
User Component renders template with user.firstName, user.lastName etc.
Initially user if an empty Object
The login service needs to set the UserService.user
The userComponent Needs to detect the change and update the DOM.
Thanks in ADVANCE!
If I'm not wrong, you are looking for a way to 'listen' to changes in your UserService.user to make appropriate updates in your UserComponent. It is fairly easy to do that with Subject (or BehaviorSubject).
-In your UserService, declare a property user with type Subject<User>.
user: Subject<User> = new Subject();
-Expose it to outside as observable:
user$: Observable<User>
...
this.user$ = this.user.asObservable();
-Login function will update the private user Subject.
login(userName: string, password: string) {
//...
this.user.next(new User("First name", "Last name"));
}
-In your UserComponent, subscribe to UserServive's user$ observable to update view.
this.userService.user$.subscribe((userData) => {this.user = userData;});
-In your view, simply use string interpolation:
{{user?.firstName}} {{user?.lastName}}
Here is the working plunker: http://plnkr.co/edit/qUR0spZL9hgZkBe8PHw4?p=preview
There are two rather different approaches you could take:
1. Share data via JavaScript reference types
If you create an object in your UserService
#Injectable()
export class UserService {
public user = new User();
you can then share that object just by virtue of it being a JavaScript reference type. Any other service or component that injects the UserService will have access to that user object. As long as you only modify the original object (i.e., you don't assign a new object) in your service,
updateUser(user:User) {
this.user.firstName = user.firstName;
this.user.lastName = user.lastName;
}
all of your views will automatically update and show the new data after it is changed (because of the way Angular change detection works). There is no need for any Angular 1-like watchers.
Here's an example plunker.
In the plunker, instead of a shared user object, it has a shared data object. There is a change data button that you can click that will call a changeData() method on the service. You can see that the AppComponent's view automatically updates when the service changes its data property. You don't have to write any code to make this work -- no getter, setter, Input, Output/EventEmitter, or Observable is required.
The view update automatically happens because (by default) Angular change detection checks all of the template bindings (like {{data.prop1}}) each time a monkey-patched asynchronous event fires (such as a button click).
2. "Push" data using RxJS
#HarryNinh covered this pretty well in his answer. See also Cookbook topic Parent and children communicate via a service. It shows how to use a Subject to facilitate communications "within a family".
I would suggest using a BehaviorSubject instead of a Subject because a BehaviorSubject has the notion of "the current value", which is likely applicable here. Consider, if you use routing and (based on some user action) you move to a new route and create a new component, you might want that new component to be able check the "current value" of the user. You'll need a BehaviorSubject to make that work. If you use a regular Subject, the new component will have no way to retrieve the current value, since subscribers to a Subject can only get newly emitted values.
So, should we use approach 1. or 2.? As usual, "it depends". Approach 1. is a lot less code, and you don't need to understand RxJS (but you do need to understand JavaScript reference types). Approach 2. is all the rage these days.
Approach 2. could also be more efficient than 1., but because Angular's default change detection strategy is to "check all components", you would need to use the OnPush change detection strategy and markForCheck() (I'm not going to get into how to use those here) to make it more efficient than approach 1.

How to change stored value in Value recipe of angular

From the angular documentation, I can see that a value recipe can be used to store some information that can be injected in different modules. So I wanted to use this for storing some user related configurations in my angular app.
What I am doing right now:
Set a value by default-
app.value('display', {
header: true,
switcher: true
})
I have a header and switcher in my views that I want to show or hide based on the value of header and switcher coming from above assignment.
This part of display and hiding works fine. What I want is that if some controller changes the value of header to false, header should then be hidden for that particular user. So from within my controller I just set the values to false. But on page refresh, these values are gone.
I am not sure what is going wrong here. Are we not supposed to change the value? If not, isn't that just a constant. In case we are not supposed to update values, what would be a better way to store some user related variables that will be available to entire app.
First make a factory like
(function() {
"use strict";
angular.module('dataModule',[])
.factory('datafactory',function(){
return {
};
});
})();
Now datafactory can be accessed any where in application just you need to inject this module in required module and factory in required controller
use like this
datafactory.myReusableVar ="something"
later on in someother controller
$scope.myLocalVar =datafactory.myReusableVar
//using session storage
var x ="value"// x can be any data type string,array, or object
sessionStorage.setItem("mySessionItem",x)
$scope.mysessionValue =sessionStorage.getItem("mySessionItem")
The problem is that on page refresh the current context is lost (including all the variables), you should resolve your issue by storing the data inside your browser's localStorge.
check this module
https://github.com/grevory/angular-local-storage

Ember js: How to retrieve the underlying model from a controller

I am trying to retrieve the underlying model object from a controller so that it can be persisted (I am not using ember-data). The obvious way would simply be:
controller.get('content');
But this doesn't work. The problem can be summed up as follows:
controller.set("content", model);
sets the content as expected and at this point
controller.get('content');
works as expected. But if I then decorate the controller with other properties eg.
controller.set('IamNotPartOfTheModel', false);
then suddenly the 'content' includes this new property. I would've expected the content to remain unchanged and the new property to only be applied to the controller itself. I understand the controller is a proxy for the model so for the most part they are treated as one and the same but surely they should still be separable when needed? The whole point of this pattern is to separate data that should be stored from data that is just temporary. Am I missing something?
To have your display specific properties out of the model, just specify them explicitly in the controller... Otherwise the controller acts as a proxy for its model... just have the property "iamNotPartOfTheModel" in your controller
App.IndexController = Ember.ObjectController.extend({
iamNotPartOfTheModel: null
})
Sample fiddle here
Your controller needs to interface to some kind of model. You can't separate the persisted model from the controller except by some kind of object reference. Even if you don't use ember-data, you'll still need to create objects which then plug into the content of the controller. Have a look at Evil Trout's blog for an implementation of ember without ember-data. Its a great starting point.

Categories

Resources