Autovivification in Vue? - angularjs

I'm transitioning from AngularJS 1.0 to Vue and one feature I'm missing a lot is the Autovivification feature of Angular, i.e. if I set this
<input type="text" ng-model="obj.key1.key2.key3.key4">
Then as soon as I enter some value in the text-field Angular automatically creates the nested Object for me inside obj, i.e. obj.key1.key2.key3.key4 = value
(Vue2 on the other hand throws an error in console: TypeError: Cannot read property 'key2' of undefined")
1. Is it possible to do in Vue? If not, why is the feature missing?
Similarly, if some nested key doesn't exists it Angular doesn't throw warnings like Vue but waits for me to create the object and it starts showing up as soon as the nested key is created
var obj = {}; //controller
View: {{obj.key1.key2}} //doesn't throw error in Angular but shows warning in Vue
2. Is there some setting for enabling the lenient mode this in Vue?
I understand that Angular and Vue are two very different frameworks, but then there is a lot of similarities (like v-model, v-for, etc) so just wondering why this is different and if it can be same or if there is a reason behind not having this?

Related

Angular2 Object Instantiation for Asynchronous Data

I was working on an angular2 project that gets an object asynchronously from the api using the new Observable framework.
this._accountsService.getAccountDetails(this.id)
.subscribe(
AccountDetails => this.accountDetails = AccountDetails,
err => this.errorMessage = <any>err,
() => console.log(this.accountDetails)
);
When we tried to access the property of that object using interpolation {{AccountDetails.UserName}} ,we got a property undefined error, because the object had not yet been received from the api. We fixed this by instantiating the object in the class
accountDetails: AccountDetails = new AccountDetails();
This works, however I noticed in Angular 1, a fake object would be created, if the object was undefined, so that there would be never be an an undefined error -- it would just show an empty value in the interpolated code. Is this a change in Angular2? Also, I noticed that when we used *ngFor in our code to iterate through the properties of an object, it would display an empty value (rather than trigger an object undefined error) if the object had not yet been received from the api. Is this something that occurs internally in the *ngFor directive?
With first piece of code you need to do following things,
1) Because it should be {{accountDetails.UserName}} (not {{AccountDetails.UserName}} ). NOTE : Please double check with U or u that I can't tell without knowing object's properties.
2) You could also use ?. like {{accountDetails?.UserName}}
I hope this will help.
Angular 2 is based off Typescript so there is stricter type checking hence the undefined error.
One thing you can do to avoid any errors is use an
*ngIf="AccountDetails.UserName"
condition on the parent tag (parent of the *ngFor loop). This way it only gets rendered once the information has been loaded from the API. You can have some loading screen with the opposite condition
*ngIf = "!AccountDetails.UserName"
so it displays till the data has been loaded and then gets swapped out once the data has been loaded.
You can remove the
accountDetails: AccountDetails = new AccountDetails();

How does AngularJS handle Memory

I am wondering how AngularJS 'saves' its data/model. Does it actually save it or.. how does it work?
We are using different methods to retrieve JSON data. In other frameworks like jQuery we had to think about how to store data locally, i.e. when we want to provide a sorting possibility. In Angular this seems different, it seems to do all that for us out of the box.
Is it that Angular displays everything how it is supposed to be and looks at changes, reads in the displayed data in and then displays it differently or does it use a local storage to save the raw json.. and work from there? (This would limit the amount of data we can feed)
Here is a simple code-example:
$http.get("url-to-json")
.success(function(returnedData) {
$scope.search_result = returnedData['search_result'];
})
From there I can just use:
<div ng-repeat='result in search_results | sortResult:"price":sorted' id="res_<% result.id %>" class="result">
Product: <% result.name %>
</div>
I am riddled how Angular still knows the data and doesn't have to load it again from the external source.
Do you know?
There is a lot more that goes into it, but essentially its all stored in local memory. Angular creates an object of all your scope properties. When you do data binding in angular you are registering an event listener and when that event is called angular loops through this object detecting if something has changed, and if so updates the object accordingly. Each time an update occurs it returns to the loop to check if anything else has been updated. This is what is referred to as the $digestLoop.
SOURCE
The ng-book

Using Angular-Bacons $scope.$watchAsProperty(property) in Angulars ng-repeat

I´m trying to find a good way to use Baconjs together with Angularjs in conjuctions with Angular-Bacon.
Now digesting from Bacon to the Angular scope works perfectly fine but I´m stumbling with Angular-Bacons $scope.$watchAsProperty(property) within Angulars ng-repeat:
Let´s say I have the Angular scope $scope.databaserecords and render it out with:
<div ng-repeat="record in databaserecords">
Each of the records has a record.checked property and I want to handle all checked records together in one Bacon stream, for example to add a certain tag to all records at once.
At this point using $scope.$watchAsProperty(databaserecords) I get no Bacon events when checking or unchecking certain records, so how could I accomplish to receive these changes back in Bacon?
I might also mention, that using $scope.$watchAsProperty(property) out of ng-repeat, for example for input fields, works well without any problem.
Thanks for your help! :)
If I've understood correctly, your actual databaserecords remains the same throughout the scope, so you'll need to invoke $watchAsProperty with the objectEquality argument set to true:
$scope.$watchAsProperty("databaserecords", true)
By default angular opts to compare objects with a simple object equality check. In your case the list object remains the same, so a deeper check is necessary. This is already implemented in angular-bacon but it seems I've omitted it from the docs.

tinyMCE aborts with "Object doesn't support this action".

I'm trying to use the AngularJS directive ui-tinymce with tinyMce 4.0.25 and IE10, and am unable to get it to work at all.
My html looks like this:
<textarea ui-tinymce ng-model="fubar"></textarea>
In my controller, I have:
$scope.fubar = "this is a <b>test</b>";
It all goes badly at these two lines in the tinymce initialization code itself.
Theme = ThemeManager.get(settings.theme);
self.theme = new Theme(self, ThemeManager.urls[settings.theme]);
The first line sets Theme to undefined and the last line aborts with the message "Object doesn't support this action". The value of ThemeManager.urls[settings.theme] is "http://localhost:57683/Scripts/tinymce/themes/modern", which seems right.
I can no longer find it, but I'd previously found a post where this issue was due to this code being executed before some other part of tinyMCE had been loaded. The solution there was to use a certain tinyMCE option that forced loading in a certain way, however that option has been removed in tinyMCE 4.x. Even more frustrating is that I had tinyMCE working for days with my own directive when suddenly this occurred. I've simplified this to just using ui-tinymce (with the same result) to rule out any of my code as the culprit.
Mea culpa! I'd switched to using tinymce.js instead of tinymce.min.js and didn't realize that the min code expects the theme to be modern/theme.min.js (which I had) but the unminified code expects the theme to be modern/theme.js.

How to avoid angular.js preemptively fetching data until certain actions

Just started out using angular.js and implemented a directive that reads from a property in the scope that's defined only when a button is clicked. The UI looks fine also because the directive part is only shown when the button is clicked. However in the console when the page is first loaded there is an error message saying "Cannot read property someProperty of undefined".
I must be violating some angular principles but I'm not sure how to fix it. Thanks for the help!
Note: Didn't do a fiddle because this is a general question.
Generally speaking, if you have code patten like
$scope.myObject.property
then you could see the error when myObject is undefined.
One possible way to eliminate the error the code work is make sure the object is always initialized when any property is intended to be referred.
You can put this line before the property is referred.
$scope.myObject = {};
Or do
if($scope.myObject !== undefined){
...
}
There is no rocket science here.

Resources