How to get a model attribute after fetch operation - javascript

I am a newbie in backbone . I wanted to know when i do the following operation how i can get the model fetched values.
For example if i do something like following
this.model.fetch();
and i want to get a value for example
this.model.get("VALUE");
How i can make sure i get the right value which is fetched right now from the server. I am trying to do something like following but ofcourse this.model is not recognized inside the complete block.
this.model.fetch().complete(function(){
window.localStorage.setItem("VALUE", this.model.get("VALUE"));
});
I am stuck here. Does anybody have any ideas.

Well, I see two options: 1. just get rid of the complete block and use the functions separately.
this.model.fetch();
var value = this.model.get('value');
//or, if you want all of the values
// var values = this.model.toJSON();
// values.value -> the specific value
And I'm not very experienced with local storage, but why are you fetching a value and then setting it to local storage?
Or, 2. You could put your inner statements in a function, and bind it to the this:
initialize: function () {
_.bind('setItem', this);
},
setItem: function() {
// assuming this code works
window.localStorage.setItem("VALUE", this.model.get("VALUE"));
}
// elsewhere, and not familiar with complete, so I'm not certain how this works
this.model.fetch().complete(setItem);

Related

$scope is not updated on camunda custom task form(Angular Js scope update)

I have external camunda form loaded. $scope.exceptionObject is not updated once i modify/Edit my form. I am not sure why it is not happening.
camForm.on('form-loaded', function() {
// fetch the variable named 'exceptionTemplate'
camForm.variableManager.fetchVariable('exceptionTemplate');
});
camForm.on('variables-fetched', function() {
// after the variables are fetched, bind the value to respective elements
var exceptionTemplate = camForm.variableManager.variable('exceptionTemplate').value;
console.log($.parseJSON(exceptionTemplate));
$scope.exceptionObject = $.parseJSON(exceptionTemplate);
console.log($scope.exceptionObject);
});
Expected Result :
$scope.exceptionObject should be updated with new value. severity:"BLOCKER" is not updated even if parsed json Object is already having updated value that is severity:"NORMAL"
I have tried to apply $scope.$apply(); for angular forums also but it is not helping. I am missing something, Why i am not able to update the scope variable ? Can anyone help ?

Knockout.js "visible" calling async function - not working

I've been trying to understand async, promises, etc. and I think I have a basic understanding of it, but I'm not getting the results I expect.
I have a HTML table, with the following:
<table data-bind="visible: viewPrincipal()">
viewPrincipal() is a function that should return true or false. This does work at the most basic level if viewPrincipal() just consists of return false or return true. But what I'm trying to do is call an async function to get the true or false value from there.
function viewPrincipal() {
console.log("Seeing if person is in principal group");
return IsCurrentUserMemberOfGroup("Principal Members", function (isCurrentUserInGroup) {
console.log(isCurrentUserInGroup);
return isCurrentUserInGroup;
});
}
The console.log works, and returns a true or false as I'd expect it to. But I want the parent viewPrincipal() function to return that true or false value, and all I get is "undefined".
I understand why this is happening - the IsCurrentUserMemberOfGroup() function is taking a bit of time to complete - but I don't know how to fix it. I know how to chain functions together, but when I'm trying to use something like knockout.js to determine if a table should be visible or not, I don't know how to chain.
Can anyone help?
The best way is to use an observable bool, and let your a-sync function change it's value. Let the magic of two-way-bindings do the rest.
Example:JSFIDDLE
function vm() {
this.viewPrincipal = ko.observable(false);
};
var vm = new vm();
ko.applyBindings(vm);
function fakeAsync() {
setTimeout(() => {
vm.viewPrincipal(true);
}, 1500);
}
fakeAsync();
I am a bit lost with your approach, but I'll try to help.
First, please double-think whether you really want to implement access control on the client side. Simply hiding an element if the user does not have sufficient rights is pretty dangerous, since the (possibly) sensitive content is still there in the DOM, it is still downloaded, all you do like this is not displaying it. Even a newbie hacker would find a way to display it though - if nothing else he can simply view it using the F12 tools.
Second, is that triple embedding of functions really necessary? You have an outermost function, that calls a function, which, in turn, calls the provided callback. You could clear this up by using computed observables:
function viewModel() {
var self = this;
var serverData = ko.observable(null);
this.viewPrincipal = ko.computed(function() {
var srvDataUnwrapped = serverData(); // access the inner value
if (!srvDataUnwrapped) {
return false;
}
// Do your decision logic here...
// return false by default
return false;
});
// Load the permission details from the server, this will set
// a variable that the viewPrincipal depends on, this will allow
// Knockout to use its dependency tracking magic and listen for changes.
(function() {
$.ajax(url, {
// other config
success: function (data) {
serverData(data);
}
);
})();
};
var vm = new viewModel();
and then in your view:
<table data-bind="visible: viewPrincipal">
note the lack if ()'s here, it is an observable, so Knockout will know how to use it.
If this seems overly complicated to add to your already existing code, then you could simply define an observable instead, and set the value of that inside your callback:
function viewModel() {
// other stuff ...
this.viewPrincipal = ko.observable(false);
// Call this wherever it fits your requirements, perhaps in an init function.
function checkPrincipal() {
IsCurrentUserMemberOfGroup("Principal Members", function (isCurrentUserInGroup) {
viewPrincipal(isCurrentUserInGroup);
});
};
};
With this approach, the markup would be the same as in the previous one, that is, without the parentheses:
<table data-bind="visible: viewPrincipal">
Doing it this way will simply set the inner value of an observable inside the callback you pass to IsCurrentUserMemberOfGroup, and because Knockout is able to track changes of observables, the value change will be reflected in the UI.
Hope that helps.

Ember.js find with plain object is not working

I use Ember.js to get items like this:
App.MyData.find()
And to get item like this:
App.MyData.find(itemId)
And then I use filter and return it in model function like this:
App.MyRoute = Ember.Route.extend({
model: function() {
return App.MyData.find().filter(function(a)
{
return a.get('desc') != null;
});
}
});
And it's working just fine.
Now I wanted to pass another parameter to underlying PHP script returning items. So I used "Querying For Records desc":
"If you provide a plain object as the second argument to find, Ember Data will make a GET request with the object serialized as query params. This method returns DS.PromiseArray in the same way as find with no second argument."
According to the documentation it should behave the same way like find with no plain object argument.
But it does not. My view is not displaying anymore.
I checked GET request. It returns exactly the same data.
I have no errors in JS.
What to do to pass parameter to PHP while getting items in a way it will work?
As you can see in this jsbin it does work. So if it doesn't work for you you either have a really old version or you're doing something else wrong.
I use this to get the model:
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('thing', { beer: 'heineken' });
}
});
and that results in this request: GET /things?beer=heineken".

Best way to track initial mapping using KnockoutJs

I find that in my application I have the following pattern repeated a lot (see below code).
I have to call BindMyEvents(true) for the first load, and then BindMyEvents(false) for subsequent data retrieval.
It is lazily loaded in, so I don't want the data serialised into the HTML source. Is there a better way than having to pass in a boolean flag into my Bind() method? Is there a standard pattern to achieving this with knockout?
I was thinking should I just set viewAlertsModel.alerts = null inside the view model definition, then let the Bind function check this. If set to null then call the mapping method followed by the applyBindings()?
function BindMyEvents(initialMap) {
// get alerts, map them to UI, then run colorbox on each alert
$.getJSON("/Calendar/MyEvents/", {},
function (data) {
if ( initialMap ) {
// set-up mapping
viewAlertsModel.alerts = ko.mapping.fromJS(data);
ko.applyBindings(viewAlertsModel,$("#alertedEventsContainer")[0]);
} else {
// update
ko.mapping.fromJS(data, viewAlertsModel.alerts);
}
});
}
I would re-arrange your code for a different flow.
first - define you data once.
viewAlertsModel.alerts = ko.observable();
Second, bind your data
ko.applyBindings(viewAlertsModel,$("#alertedEventsContainer")[0]);
Third, now work with your data
$.getJSON("/Calendar/MyEvents/", {},
function (data) {
ko.mapping.fromJS(data, viewAlertsModel.alerts);
});
Steps one and two can be done during an initialization phase. The key here is first define viewAlertsModel.alerts as an observable.
Step three is your run-time code. Now, your initialization code is completely separate from your run-time code. This the more the normal knockout style.
edit
With regards to your comments about using ko-mapping, I use the following code
var tempVar = ko.mapping.fromJS(data);
viewAlertsModel.alerts(tempVar); // !important - do not use = operator.
This is the convention that most people use. Your use of ko-mapping is normally used for specialized situations.

Strange JavaScript behaviour, variable changing value before converter function is called

I'm passing down some JSON data from Smarty. I'm applying this to a JavaScript variable, options.
If you've seen my previous question about date formats you'll know I need to do a bit of work on the data coming in, so I've got a function called chart_convert_dates() that's called, passing in the options (well, options.data), and upon it's return setting it back again.
If you read through my code you'll notice I'm debugging the options variable, and it changes from the original before the function is called!?
If I comment out the function call, the variable is untouched, as it should be at that point.
This happens with Chrome, FF... what's going on?
{literal}
<script type="text/javascript">
$(document).ready(function() {
// set JS var, this data is coming in from smarty
var options = {/literal}{$options}{literal};
// these should both be exactly the same
debug.debug({/literal}{$options}{literal});
debug.debug(options);
// but the above outputs aren't the same! options has been modified
// by the function below... that hasn't even fired yet!? We can prove
// this by commenting out the following function call
options.data = chart_convert_dates(options.data);
// ... do something else
});
</script>
{/literal}
This is, of course, impossible.
You'll probably find that the debug.debug() function is saving a reference to the object it is provided with, rather than converting it to a string immediately. When you then view the contents of it's argument at a later time, the output will reflect the current state of the object, rather than the state it was in.
This is best explained with the following example:
var debug = {
report: function () {
// console.log(this._value);
},
debug: function (arg) {
this._value = arg; // save a reference
}
}
var options = {
foo: 1
};
debug.debug(options);
options.foo = 2;
debug.report(); // will show 2 (http://jsfiddle.net/zQFPm/)
http://jsfiddle.net/zQFPm/

Categories

Resources