Updating model without scope in AngularJS - angularjs

I have been searching for answers for several hours and I think I need to add a separate question. I have the following table and controller:
<table class="table table-striped">
<thead>
<tr>
<th>value</th>
<th>datapoint</th>
</tr>
</thead>
<tr ng-repeat="obj in cont.objs">
<td>{{ obj.value }}</td>
<td>{{ obj.datapoint }}</td>
</tr>
</table>
<button>Next</button>
objects.controller.js
(function() {
'use strict';
angular
.module('app.objects')
.controller('ObjectsController', ObjectsController );
ObjectsController.$inject = ['objectsService', '$state', '$stateParams', '$uibModal', 'logger'];
function ObjectsController(objectsService, $state, $stateParams, $uibModal, logger) {
var cont = this;
activate().then( function successCallback(selectObjects) {
cont.objects = loadObjects(selectObjects._links.objects.href);
});
}
function loadObjects(uri) {
...
cont.objects = getObjects(uri)
return cont.objects;
}
...
I have a button 'Next' and when pressed, needs to update cont.objects by fetching new cont.objects from the api by calling loadObjects with the original uri + '/2'.
I thought maybe
<button ng-click="cont.loadObjects(cont.objects.next.href)">Next</button>
would work, but I get an error saying loadObjects is undefined. Any ideas?

Hope you had defined activate() function and to make this work use
controller As with the controller definition and make sure you are clicking the button after the success of activate() function .
https://toddmotto.com/digging-into-angulars-controller-as-syntax/

You're not binding that function to scope. You need to add that function inside of your controller and bind it.
function ObjectsController(objectsService, $state, $stateParams, $uibModal, logger) {
var cont = this;
cont.loadObjects = loadObjects;
function loadObjects(uri) {
cont.objects = getObjects(uri)
return cont.objects;
}
activate().then(function successCallback(selectObjects) {
cont.objects = loadObjects(selectObjects._links.objects.href);
});
}

Related

Can't access $scope variables after changing view with $location.path

I'm trying to access data that is on the $scope on a view where the app lands after clicking a button but it seems as if after using $location.path(url) to do the redirection the APP cannot see a variable that exists on the $scope anymore.
Form with the button:
<form ng-submit="getBrokenProbes()">
<table class="table table-striped">
<tr>
<th>Bmonitor</th>
<th>Select Bmonitor</th>
</tr>
<tr ng-repeat="bmonitor in bmonitors">
<td>
<span>{{bmonitor.domainName}}</span>
</td>
<td>
<button class="btn btn-primary" ng-click="getBrokenProbes(bmonitor)">Request</button>
</td>
</tr>
</table>
</form>
Controller:
app.controller('logmeinValidationCtrl', ['$scope','$http', '$location', function($scope,$http, $location){
$scope.bmonitors = {};
$scope.brokenProbes = {};
$http.get('http://localhost/getBmonitors').success(function (data) {
$scope.bmonitors = data;
console.log($scope.bmonitors);
});
$scope.getBrokenProbes = function(bmonitor) {
let url = 'http://localhost/getBrokenProbes';
$http.post(url, bmonitor).then(function (response) {
$scope.brokenProbes = response.data.hosts;
console.log($scope.brokenProbes);
$scope.showBrokenProbes();
})
};
$scope.showBrokenProbes = function () {
$location.path('/logmeinValidationResult')
}
}]);
I'm trying to show that data in a different view but $scope.brokenProbes is not available in logmeinValidationResult.html (the page where I land after $location.path) so it just shows an empty table.
logmeinValidationResult.html
<table class="table table-striped">
<tr>
<th>Probe name</th>
</tr>
<tr ng-repeat="probe in brokenProbes">
<td>
<span>{{probe.description}}</span>
</td>
</tr>
</table>
New page controller:
app.controller('logmeinValidationResultCtrl', ['$scope', function($scope){
console.log($scope.brokenProbes); //This yields undefined
}]);
I) The variable $scope.brokenProbes belongs to the controller logmeinValidationCtrl where is defined...
In order to use it inside another controller, you should pass it - broadcast.
OR
II) Another (Better) solution is when the user gets redirected to logmeinValidationResult, you can call the API, get the data and assign to $scope.brokenProbes variable.
In that case,
your old controller should look like this:
app.controller('logmeinValidationCtrl', ['$scope','$http', '$location', function($scope,$http, $location){
$scope.bmonitors = {};
$http.get('http://localhost/getBmonitors').success(function (data) {
$scope.bmonitors = data;
console.log($scope.bmonitors);
});
$scope.getBrokenProbes = function(bmonitor) {
$location.path('/logmeinValidationResult/' + bmonitor); // Pass bmonitor to the result here so you can call the api with that parameter later on
};
}]);
And your here is how your new page controller should look like:
app.controller('logmeinValidationResultCtrl', ['$scope','$http', '$routeParams', function($scope,$http, $routeParams){
$scope.brokenProbes = [];
let url = 'http://localhost/getBrokenProbes';
let bmonitor = $routeParams.bmonitor; // Get passed bmonitor value from the route params
$http.post(url, bmonitor).then(function (response) {
$scope.brokenProbes = response.data.hosts;
console.log($scope.brokenProbes);
})
}]);
And don't forget to register route param bmonitor to your $routeProvider or whatever you use...

Pass json to angular controller

i want to pass a json file or object to an angular controller to use it with ng-repeat.
My json object is stored in my index.js file and written to data.json. My controller.js file looks like the following:
var fs = require('fs');
var jobs = fs.readFile('out/data.json', 'utf-8', (err, data) => {
if (err) throw err;
});
angular.module('slrm', [].controller('slrmctrl', function($scope) {
$scope.data = jobs.data;
}));
And thats my html file:
<table class="table">
<thead>
<th scope="col">#</th>
<th scope="col">JOBNAME</th>
<th scope="col">USER</th>
<th scope="col">NODE</th>
<th scope="col">CPUS</th>
<th scope="col">START</th>
<th scope="col">STATE</th>
</thead>
<tbody ng-app="slrm" ng-controller="slrmctrl">
<tr ng-repeat="x in data | orderBy : 'JOBID'">
<td>{{ x.JOBID }}</td>
<td>{{ x.NAME }}</td>
<td>{{ x.USER }}</td>
<td>{{ x.NODELIST }}</td>
<td>{{ x.CPUS }}</td>
<td>{{ x.STATE }}</td>
<td>{{ x.REASON }}</td>
</tr>
</tbody>
</table>
<script src="js/controller.js"></script>
Now I have 2 questions. Im providing this html with:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/view/index.html');
});
var server = app.listen(3000, function() {
console.log('Server running');
};
Is the controller.js file even imported? because bootstrap.css is not imported somehow.
The other Question is if the line
$scope.data = jobs.data;
is even working? Should I read the file or use the exported object from index.js? How do I export only this one object?
I built this from scratch because im very new to js and stuff.
Thank you!
I think the issue lies in your module and controller declaration.
When declaring a module, you have to instantiate it first, by passing it's dependencies.
angular.module('slrm', []);
Afterwards, you can attach a controller to the module
angular.module('slrm').controller('slrmctrl', function($scope) {
$scope.data = jobs.data;
}));
Secondly, instead of reading the data.json object externally and passing it to controller, why don't you read the data inside your controller?
angular.module('slrm').controller('slrmctrl', ['$scope', '$http', function($scope, $http) {
$http.get('out/data.json')
.then(function(response) {
$scope.data = response.data;
});
}]);
EDIT to show example of timer (polling) implementation
angular.module('slrm').controller('slrmctrl', ['$scope', '$http', '$timeout', function($scope, $http, $timeout) {
$scope.refreshInterval = 900; // Sec (15 Minutes)
$scope.getData = function () {
$http.get('out/data.json')
.then(function(response) {
$scope.data = response.data;
return $timeout($scope.getData, $scope.getTimeLeftToRefresh());
});
};
$scope.getTimeLeftToRefresh = function () {
var now = new Date();
var timeLeftToRefresh = ($scope.refreshInterval - (now.getMinutes() * 60 + now.getSeconds()) % $scope.refreshInterval) * 1000;
return timeLeftToRefresh;
};
// Initial call to start the loop
$scope.getData();
}]);

Passing values from controller to controller in AngularJs using Factory

I trying to pass a value from controller1 to controller2 using factory on ng-click, now i have added routing
var app = angular.module("myApp", ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('ShowData', {
url: '/ShowData',
templateUrl: '../Pages/Show.html'
})
.state('EditData', {
url: '/EditData',
controller:'Editctrl',
templateUrl: '../Pages/Edit.html'
})
});
app.controller('Controller1', function ($scope, $http, Phyfactory) {
//Here I am calling a factory
$scope.open = function (name) {
var message = name;
console.log('Hcpname', message);
Phyfactory.set(message);
$location.url('/EditData');
// this is my second controller
app.controller('Editctrl', function ($scope, Phyfactory) {
alert('cntrl2');
$scope.fks = Phyfactory.get();
});
I want to bind this value to textbox
<div ng-controller="Controller2">
Name: <input type="text" ng-model="fks" />
</div>
//this is my factory
app.factory("Phyfactory", function () {
var phyname = {};
function set(data) {
phyname = data;
alert('Inside set :' + phyname);
}
function get() {
alert('Inside get :' + Object.values(phyname));
return phyname;
}
return {
set: set,get:get
}
})
Adding HTML part for controller1 as requested, i am calling ng-click inside td
<div ng-app="myApp" ng-controller="controller1"
<table class="wtable">
<tr>
<th class="wth">
A
</th>
<th class="wth">
B
</th>
</tr>
<tr ng-repeat="tab in Phyperform | filter:search.view_nm|filter:search.time_period|filter:search.team_nm">
<td class="wtd" ><a ng-click="open(tab.A)"> {{tab.A}} </a> </td>
<td class="wtd"> {{tab.B}} </td>
</tr>
</table>
Value is not passing to controller2 and not redirecting as well.
Any idea?
window.location.href
will redirect to out of the app, you must use routing with $location.
of course a better way to pass data between controllers is using event!
using event like below :
this is event receiver in controller 2:
$scope.$on('myCustomEvent', function (event, data) {
console.log(data); // 'Data to send'
});
and this is the sender event in controller 1:
$scope.$emit('myCustomEvent', 'Data to send');
Credit goes to this post "Sharing Data between pages in AngularJS returning empty"
I able to do using sessionStorage.

Getting error data not found using bootstrap datatable with angularjs

I used all possible dependencies available on net but couldn't able to solve the issue.
Back End code is written using ASP .NET and MVC returns Json data.
Below is my controller Code
var app = angular.module('myTaskFormApp', [])
app.controller('MyTaskController', function ($scope, $http, $location, $window) {
$scope.TaskModel = {};
$scope.message = '';
$scope.result = 'colour-default';
$scope.isViewLoading = false;
$scope.List = null;
$scope.List1 = null;
var TaskNo = getQueryVariable('TaskNo');
getallData();
//******=========Get All Resources=========******
function getallData() {
debugger;
$http.get('/Dashboard/GetMyTasks?TaskNo=0').then(function (data, status, headers, config) {
$scope.List = data.data;
$('.dataTable-length').dataTable();
}, function (data, status, headers, config) {
$scope.errors = [];
$scope.message = 'Unexpected Error while saving data!!';
console.log($scope.message);
});
};
});
I tried using datatable='ng' even that din't work.
Below is my HTML Code.
I'm getting data but at last I'm getting
No data found
.
As I click the table to sort my data; all data is wiped out.
Anchor tag is also not working in the link. The link never hits the controller.
<table class="table table-striped table-bordered tab-pane dataTable-length" cellspacing="0" width="100%">
<thead>
<tr>
<th>Task Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="TaskModel in List | filter : paginate | filter:search" ng-class-odd="'odd'">
<td>{{TaskModel.TaskName}}</td>
<td>{{TaskModel.Status}}</td>
</tr>
</tbody>
</table>
Im getting Data Not found at bottom of table

Change the url without reloading the controller in Angularjs

Initially, I am showing all the users name in the table. Once the user selected any one of the name, I call the LoadData method with the selected user as the parameter. I am changing the url #/Trades/User/User1 and append the details under the User1. My requirement is 1) In the LoadData method, I want to change the url to as #/Trades/User/User1 or #/Trades/User/User2 based on the selection 2) It should update the data and reflect in view, but it should not reload the controller.
HTML
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat-start="val in data.Titles" class="h" ng-click="LoadData(val.title)">
<td colspan="2" ng-hide="val.title == undefined">{{val.title}}</td>
</tr>
<tr ng-repeat="con in val.details">
<td>{{con.portfolio}}</td>
<td>{{con.status}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="2">Load More</td>
</tr>
</table>
</div>
Code
angular.module("myApp", [])
.controller("myCtrl", ["$scope", function ($scope) {
$scope.data = {"Titles":[{title:"User 1",
details: [{portfolio: "Microsoft", status:"Active"},{portfolio:"IBM", status:"Inactive"}]
}, {title:"User 2",
details: [{portfolio: "Yahoo", status:"Inactive"},{portfolio: "Google", status:"Active"}]
}]};
$scope.LoadData = function(id) {
Change the url as #/Trades/Author/User1
Load the details of the User1
};
});
You could try this. I am using this currently in my project for something very similar. http://joelsaupe.com/programming/angularjs-change-path-without-reloading/
app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
var original = $location.path;
$location.path = function (path, reload) {
if (reload === false) {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function () {
$route.current = lastRoute;
un();
});
}
return original.apply($location, [path]);
};
}])

Resources