How to reload an angular controller with the updated $scope? - javascript

My problem is I need "det" value applied to the controller and reload it.
Anyway nevermind it and continue reading first so you will understand my question.
I have this controller below.
At first load, the xxx isn't going to exist in the object then det value will be null. So it is expected that the controller's service will have an error telling that it can't be find. (See Controller code below)
However, when I click a button on my page (buttons html code is not here, I don't think it is necessary), it fills the object in and I'm wishing to reload the controller so I will see my expected output.
The HTML below is the one who loads the controller, what I'm expecting is that the
data-ng-model="{{$parent.$root.ParentItems['xxx'].xxx}}" will update the xxx value in controller. And it actually does because I'm using "<span>{{$parent.$root.ParentItems['xxx'].detnumber}}</span>" to test it.
Now, again,
My problem is I need the "det" value applied to the controller and reload it.
What I'm thinking is to create a new controller but I will just repeat the code.
//html
<div data-ng-switch-when="thisIsIt" ControllerOne data-ng-model="{{$parent.$root.ParentItems['xxx'].xxx}}"></div>
<span>{{$parent.$root.ParentItems['xxx'].xxx}}</span>
//Attribute ControllerOne
controller: function ($scope, $element, $http) {
function par() {
var xxx= null;
xxx = $scope.$parent.$root.ParentItems['xxx'].xxx;
var det = { xxx: xxx};
return det;
}
$http.post('/api/values/entries/GoHere', par()).success(function (salData) {
var buildSHGraph = function (shData) {
//code code codes...
}
$scope.Array1 = [];
angular.forEach(salData, function (evt) {
//Code Code Codes
});
buildSHGraph($scope.Array1);
});
}

I thing you can use $rootScope and pass your value to it. Then the value can be accessible globally by your application.
When your value is downloaded from ajax, the scope/html will be updated.

When you define variable with 'var xxx' cannot access it outside of the scope of this function, in your case 'par'.
function par() {
this.xxx = null;
this.xxx = $scope.$parent.$root.ParentItems['xxx'].xxx;
}
When you try to change view from callback from async task such as $http.post you need to '$digest' or '$apply' the scope
//Do this in success callback function in your ajax request
$timeout(function() { //$timeout must be setup as dependency in constructor such as $scope and $http
$scope.$digest();
});

Related

Passing angular 1 controller scope method as callback to captcha library

I have a client who is based in china and requires specialised captcha that works there. The captcha I need to use is here https://open.captcha.qq.com/
Basically there are 4 steps to get it working:
In the label of html, add this line:
<script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
Add id and property to any DOM element that we want to activate captcha, such as button, div or span. Sample code as below:
<button id="TencentCaptcha"
data-appid="2090807227"
data-cbfn="callback"
>验证</button>
Then create callback function in javascript:
function callback(res){
console.log(res)
if(res.ret == 0){
alert(res.ticket) // ticket
}
}
From the callback, make a POST request to the server to validate the ticket
I'm struggling this to incorporate this into my UI which uses Angular 1.5.6.
My controller is:
.controller('MyCtrl', function($scope) {
$scope.oldCallback = function(){
console.log('in the old callback');
};
$scope.newCallback = function(){
// PASS THIS AS THE CALLBACK TO NEW REGISTER BUTTON
};
})
I have created a CodePen here.
The only way I can get it remotely working is if I pass in a method in the HTML e.g.
<button type="submit" id="TencentCaptcha"
data-appid="2090807227"
data-cbfn="(function(res){alert('res is ' + res)})">
Register
</button>
After clicking Register, the captcha library presents a popup with a challenge to the user. Once completed, the callback passed to data-cbfn is executed. How can I call my controller method from this callback, passing through the result?
I created a global function and was then able to call the correct method in the controller:
function callback(){
var scope = angular.element(document.getElementById("home")).scope();
scope.register();
}
You could also add your function to the window from your angular controller:
.controller('MyCtrl', function($scope, $window) {
$window.callback = function callback(res) {
$scope.register();
};
});
This way you don't have to request the document element which may change scope or id later on.
Also: $compileProvider.debugInfoEnabled(false); will actually disable the functionality to retrieve the scope from a document element like you've done.
You should be turning off the debugInfo functionality in production mode for performance and security reasons.

Getting access to angular $scope from own event

$I have a custom javascript object, that can fire events.
I would like to access the angular $scope inside the event-handler, but I have read somewhere that using angular.element(...).scope() is not good, because it's only meant for testing.
My other idea was to register the handle on my object inside the controller, but this is not working (looks like $scope.somevalue gets set, but I don't think $scope is the same object).
I have found many answers here on Stack Overflow for similar questions, but they all seem to be using directives. All I want is to get a value from the object when it's updated, and display it.
Here are the two ways I have tried.
var myObj = GetMyObjInstance();
// Working, but apparently it's not good practise to call .scope() on an element.
myObj.onUpdated = function(){
console.log("myObj updated");
var v = myObj.getValue();
var controllerDiv = document.getElementById("controller");
var $scope = angular.element(controllerDiv).scope();
$scope.apply(function(){
$scope.someValue = v;
});
}
// Tried to do this, thinking i would get closure on the scope.
angular.module('myApp', []).controller('controller', function($scope){
myObj.onUpdated = function(){
console.log("myObj updated"); // Gets logged to console...
var v = myObj.getValue();
$scope.somevalue = v; // ... but somevalue does not get displayed.
$scope.apply(); // Error, says it's not a function, so maybe this is not the right object?.
}
});
Use AngularJS directives to handle events and update scope.
app.directive("xdEvent", function() {
return linkFn(scope, elem, attrs) {
elem.on("event", function(e) {
scope.$eval(attrs.xdEvent, {$event: e});
scope.$apply();
});
};
};
USAGE
<div xd-event="fn($event)"></div>
I think using a Service instead of a controller is a better practice. You can call a service from outside javascript with the injector like explained in this thread :
Call angularjs service from simple js code
If it is still important for you to access this variables from controller, you can use $watch to tell your controller to update itself when the service variables change.
Hope this help.
A+

AngularJS don’t get JSON data

I want to get data from a JSON file by using $http.get with AngularJS.
I use the "new way" to write AngularJS scripts (link).
PLUNKER
Nothing happens, Firebug tells me nothing.
I think the problem is in my activate() function code, I don’t really understood the promises.
function activate() {
return $http.get('test.json').then(function(data) {
vm.result = data;
return vm.result;
});
}
Have you an idea about this ?
I see a couple of problems.
First, in your plunker code you have:
controller.$inject = ["$http"];
function controller() {
You are missing the $http parameter in your controller function signature.
function controller($http) {
Once I fixed that, I found your index.html page was binding to {{c.value}}, but your controller never defines a value property. Maybe this should be {{c.result}}? If I make these changes I get a visible result.
You're not able to return at that point in your then callback. Simply return the $http call itself, of which will be a promise, and resolve it. Also, your console should be telling you something like $http is undefined since you did not inject this service properly. Observe the following...
function activate() {
return $http.get('test.json')
}
[...]
activate().then(function(response) {
vm.result = response.data;
});
Plunker - demo
Side note - you'll likely want to wrap activate() into an reusable service to keep this logic out of our controllers, so we'll instead inject the defined service into controller instead of $http directly.
Plunker - demo with this logic wrapped in a simple service

Angular Resolve Scope Issues

I'm a junior developer and have been learning the ins and outs of Angular.js. I recently started using the resolve feature of the route provider to get my Project data from my service before the page loads. Before that I was calling my service inside the controller to get the data. My problem is that when I use resolve, the data gets to the controller just fine, but my scope doesn't take in my functions present at the bottom of the code and I'm not particularly sure why. If I move the function declarations to the top it works fine. My guess is that since the page now loads with the data, it doesn't have time to check the entire controller and instead just runs down it in order. Can anyone confirm why it's occurring and a solution so I can keep my code nice and readable? Thanks
My Route Provider
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/details/:id', {
templateUrl: '/HtmlViews/Details.html',
controller: 'detailController',
resolve: {
project: function (projectService, $rootScope, $route) {
$rootScope.loading = true;
return projectService.getProjectById($route.current.params.id);
}
}
});
}])
My Controller (stripped to just the important stuff) In it's state below, the program can't find function getDateAt in the scope when it needs to.
.controller('detailController', function ($scope, $http, $rootScope, projectService, project) {
$rootScope.loading = false;
$scope.id = project.ID;
$scope.project = project;
$scope.sprintCountRounded = projectService.roundSprintCount($scope.project.SprintCount, $scope.project.RoundUp);
// Check and alter data depending on if a start date is present on the project
$scope.isDateMissing = $scope.project.StartDate === undefined || $scope.project.StartDate === null;
if (!$scope.isDateMissing) {
$scope.startDate = $scope.getDateAt(0);
$scope.finalSprintStart = $scope.getDateAt($scope.sprintCountRounded);
$scope.finalSprintEnd = $scope.getDateAt($scope.sprintCountRounded + 1);
}
$scope.NumberOfLoggedSprints = $scope.project.Sprints.length;
$scope.getDateAt = function (sprintNum) {
return projectService.getDateAt(sprintNum, $scope.project.SprintDuration, $scope.project.StartDate);
}
});
JavaScript processes code 'top down' (somewhat), so to speak, as it is an interpreted language. So as your code is processed line by line, once it reaches the lines inside your conditional that have $scope.getDateAt(), it attempts to call the function on your scope object. But the problem is this: your function hasn't been defined yet, as JavaScript hasn't processed the line where your function is defined.
As you noticed, by placing your function definition at the top, it works perfectly fine, as that code is processed first. This typically happens when you declare inline functions.
The exception to this is explicit function definitions. Were you to do the following code instead, it would work regardless of where you place the getDateAt() function:
function getDateAt(sprintNum) {
return projectService.getDateAt(sprintNum, $scope.project.SprintDuration, $scope.project.StartDate);
}

AngularJs call parent controller function with parameter

I have two controller's and I want to call other parent controller function with parameter when user clicks the button.
Html
<a ng-click='test('something')'>Click</a>
Controller
controller: function($scope) {
..........
$scope.test= $scope.$parent.parentTest(t);// it fails...
..........}
Parent Controller
$scope.parentTest= function(m) {
var my=m;
...Something...
}
If I run function without any parameter, it works. If I run the function with parameter it doesn't.
I want to call parent function with parameter.
The mistake in your code is with this line:
//This assigns the RESULT of parentTest() to $scope.test
$scope.test= $scope.$parent.parentTest(t);
// Either of the 2 options below will probably work for you.
//This assigns the parentTest Function itself to $scope.test
$scope.test= $scope.$parent.parentTest;
//This wraps it safely in case the parentTest function isn't ready when
// this controller initializes
$scope.test= function(t){$scope.$parent.parentTest(t)}; // << Change it to this!
Check this plunkr, maybe this can help you
plunkr
access parentfunction in child controller

Categories

Resources