AngularJS: How to call function on $resolved - javascript

I am using a MEAN stack. Upon loading a page, I am pulling data. Based on that data, I am making calculations.
I was trying to do calculations based off the model being $resolved. I was looking to see if there was an event I could trigger from?
Here is what is being called on ng-init
// Find existing Vital
$scope.findOne = function () {
$scope.vital = Vitals.get({
vitalId: $stateParams.vitalId
});
};
If I try to call my calculate() right away, like below, it fails because data isn't there yet
// Find existing Vital
$scope.findOne = function () {
$scope.vital = Vitals.get({
vitalId: $stateParams.vitalId
});
$scope.calculate();
};

Try this:
$scope.findOne = function () {
$scope.vital = Vitals.get({
vitalId: $stateParams.vitalId;
$scope.calculate();
$scope.$apply()
});
};

Related

How to use Callback functions in Class with JavaScript/jQuery

I have a class I am using for creating CRUD Objects for my site.
It stores the form and table paths for adding, listing, editing and deleting the data, as well as reloading your view with ajax after each edit.
Here is my class definitions:
class CRUDObj{
constructor(containerSel, links) {
this.links = links;
this.containerSel = containerSel;
this.formCallBack = function(){};
}
setActive(obj_id){
$.post(this.links.editURL+'?'+obj_id, {status:"active"}, this.reload);
}
reload(returnData){
this.formCallBack(returnData);
this.formCallBack = function(){};
if($(this.containerSel).length > 0){
ajaxLoad(this.links.listURL, $(this.containerSel));
}
}
}
A basic instance of initializing it:
var contactObj = new CRUDObj('#contacts', {
editURL: '/contact.edit.php',
listURL: '/contacts.list.php',
});
contactObj.formCallBack = function(){
console.log('Custom Reload Callback');
};
The problem appeared when I tried to add the callback, so that I could run a custom function during the refresh.
Running contactObj.setActive(); works properly, and my refresh function is called after the form submits, but when it hits my callback I get:
Uncaught TypeError: this.formCallBack is not a function
Calling it manually contactObj.refresh(); works smoothly.
How can I pass this callback function through better?
The problem is that you're passing method as function, so you loose this context. this will be window object or undefined (if using strict mode):
You need this:
var self = this;
lightboxForm(this.links.editURL+'?'+obj_id, function(x) { self.reload(x) });
or using ES6
lightboxForm(this.links.editURL+'?'+obj_id, x => this.reload(x));
or using bind to return function with given context:
lightboxForm(this.links.editURL+'?'+obj_id, this.reload.bind(this));

How to pass a ReactJS function as a callback to a external JS function?

I am implementing a credit card payment form in ReactJS using a 3rd party bank JS which works using iframes.
The logic is I load bank's javascript in my page, something like this:
<script src="https://my-bank.com/super-secure-script.js"></script>
Then I collect user's CC data in my ReactJS component, then call a function like this:
window.Bank.SendPayment(CC, this.paymentCompletedCallback);
...
paymentCompletedCallback = (result) => {
// process payment result here, inside my component
}
The problem is: the code inside super-secure-script.js cannot find the callback this.paymentCompletedCallback, because it is inside inside my component.
The question is: how can I pass to an external script a reference to a react object function?
You can attach the function to the window object:
const Component = () => {
const func = () => {
console.log('do something');
};
window.func = func;
};
this.paymentCompletedCallback.bind(this) may solve the problem.
Here is another example of when binding is necessary, hope that makes it more clear to you:
var Button = function(content) {
this.content = content;
};
Button.prototype.click = function() {
console.log(this.content + ' clicked');
};
var myButton = new Button('OK');
myButton.click();
var looseClick = myButton.click;
looseClick(); // not bound, 'this' is not myButton - it is the global object
var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton

Why doesn't this function run when the reactive variable changes value?

I'm new to meteor and I'm trying to get a hang of the whole reactivity thing.
There isn't a specifc reason why I want this function to re-run, in fact, it not re-running is actually the desired behavior for my use case. I just want to know why this is happening so I can better understand the concepts.
If I add a function as a property on a template instance, like this:
Template.services.onCreated( function() {
this.templates = [
"web_design",
"painting",
"gardening"
];
this.current_index = new ReactiveVar(0);
this.determineSlideDirection = function() {
console.log(this.current_index.get());
};
});
And then I update the reactive var in response to some event.
Template.services.events({
'click .nav-slider .slider-item': function(event, template) {
var new_selection = event.currentTarget;
template.current_index.set($(new_selection).index());
}
});
The function is not re-run upon the invocation of the set() call.
However, If I have a helper that utilizes the variable, it will be re-run.
Template.services.helpers({
currentTemplate: function() {
var self = Template.instance();
return self.templates[self.current_index.get()];
}
});
Why is this?
Reactive data sources only cause some functions to automatically re-run. These functions are:
Tracker.autorun
Template.myTemplate.helpers({})
Blaze.render and Blaze.renderWithData
In your code above you would want to use Tracker.autorun
Template.services.onCreated( function() {
this.templates = [
"web_design",
"painting",
"gardening"
];
this.current_index = new ReactiveVar(0);
Tracker.autorun(function(){
// actually, this might not work because the context of
// 'this' might be changed when inside of Tracker.
this.determineSlideDirection = function() {
console.log(this.current_index.get());
};
});
});

How to form callback when using context.executeQueryAsync delegates in javascript

Sorry for yet another question about callbacks. In trying to solve this problem, I've run across about a million of them. However, I'm having trouble wrapping my head around this particular scenario.
I have the code below, which obviously doesn't work as delegates apparently don't return values (I'm learning as I go, here). So, I know I need a callback at this point, but I'm not sure how to change this code to do that. Can anyone help?
function MyFunction() {
var ThisLoggedInUser = checkCurrentUser();
//do some stuff with the current user
}
function checkCurrentUser() {
var context = SP.ClientContext.get_current();
var siteColl = context.get_site();
var web = siteColl.get_rootWeb();
this._currentUser = web.get_currentUser();
context.load(this._currentUser);
context.executeQueryAsync(Function.createDelegate(this, this.CheckUserSucceeded),
Function.createDelegate(this, this.CheckUserfailed));
}
function CheckUserSucceeded() {
var ThisUser = this._currentUser.get_title();
return ThisUser;
}
function CheckUserfailed() {
alert('failed');
}
Based on your comment, you have to rething the way you want your code because you cannot use ThisUser in MyFunction().
For example you could do that:
function CheckUser() { ... }
// then call the function to find the current user
CheckUser();
// then in CheckUserSucceeded you call MyFunction()
function CheckUserSucceeded() {
MyFunction(this._currentUser.getTitle())
}
// and now you can use ThisUser in MyFunction()
function MyFunction(ThisUser) {
// do something with ThisUser
}
Your CheckUserSucceed won't return anything because it's asynchronous....
So you have to do something like that:
var ThisUser;
function CheckUserSucceeded() {
ThisUser = this._currentUser.getTitle()
// here you can call an other action and do something with ThisUser
}
You may also want to check the $SP().whoami() function from http://aymkdn.github.io/SharepointPlus/ and see the documentation.

Changing the state of a toggle in JavaScript/jQuery

Is it possible to change the state of a toggle function? Like:
myDiv.toggle ... function 1 , function 2
I click on the myDiv element, the function 1 executes
I click again, function 2
I click again, function 1
BUT
Change the state
function 1 again
etc.
But I need to be able to change the state from outside the toggle function.
Here is a javascript object that uses closure to track it's state and toggle:
var TOGGLER = function() {
var _state = true;
var _msg = "function1";
var function1 = function() {
_msg = "function1";
}
var function2 = function() {
_msg = "function2";
}
return {
toggle: (function () {
_state = !_state;
if (_state) {
function1();
} else {
function2();
}
return _msg;
})
}
}();
Here is a jsfiddle that shows how to use it to toggle based with the following jquery: http://jsfiddle.net/yjPKH/5/
$(document).ready(function() {
$("#search").click(function() {
var message = TOGGLER.toggle();
$("#state").text(message);
});
});
The toggle function is meant for simple use cases. Changing the state externally is not "simple" anymore.
You cannot easily/safely (it's internal so it may change during minor versions) access the state variable of the toggle function easily as it's stored in the internal dataset of the element.
If you really want to do it, you can try this code though:
$._data(ELEMENT, "lastToggle" + func.guid, 0);
func is the function you passed to .toggle(), so you need to save this function in a variable. Here's a minimal example: http://jsfiddle.net/xqgrP/
However, since inside the function there's a var guid = fn.guid || jQuery.guid++ statement, I somehow think that the devs actually meant to use guid instead of func.guid for the _data key - in that case a minor update is very likely to break things. And after the fix you'd have to iterate over the data set to retrieve the correct key as there is no way to access the guid from outside.

Categories