How to remove unwanted databinding in Angularjs - angularjs

I have an angularjs web page page which allows me to edit some fields. I load the data from my DB, edit it in the page then save the revised data back to the DB. the DB api requires me to submit for amendments the existing DB data and the revised data. Unfortunately when I save the existing data it is binding to the change which I don't want to do !
function providerCtrl($scope, $location, $routeParams, $http)
{
$scope.getProvider = function () {
$http.get(
'/admin/api/'+$routeParams.channel+
'/'+$routeParams.provider).success(function(data){
inputData = data[0];//i want to save this initially but never have it change again, unfortunately its binding with this $scope.settings field changes :-(
$scope.settings = data[0];
});
}
$scope.amendProvider = function (settings) {
console.log($scope.inputData);
var data = {'old': inputData, 'new' : $scope.settings}
console.log(data);
$http({
url: '/admin/api/' + $routeParams.channel + '/' + $routeParams.provider,
method: "PUT",
data: {'old': inputData, 'new' : $scope.settings}
})
.success(function(data){
});
}
$scope.settings = {};
var inputData = {};
$scope.getProvider();
}

when I save the existing data it is binding to the change which I don't want to do !
use angular.copy() utility to clone new instance.
See Documentation HERE

Related

My $scope value not updating

updated object is not getting without using location.reload
Hi i will get list of objects from API where i have to update one value,After updating that value in modal popup i am not able to get new updated value without using location.reload. Is there any other solution for this.i am using two different controllers.
Will get list of objects from this
$scope.groups=response.data
will ng-repeat this groups where i will have edit button for every line,Once i click edit button popup will open
$scope.editGroup = function(u) {
$scope.groupName=u.groupName;
$scope.groupId=u.groupId;
ModalService.showModal({
templateUrl: 'app/components/modal/editGroupDetails.html',
controller: "ModalController",
scope: $scope
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = "You said " + result;
});
});
};
Next once i edit the GroupName i will click submit
$scope.updateGroupName=function(){
var data={
"groupId": $scope.groupId,
"groupName": $scope.groupName
}
url=globalUrlConfig.globalAdminApi+globalUrlConfig.updateGroup+$scope.schoolId;
$http({
method: 'PUT',
url: url,
data: data,
}).success(function(response) {
console.log(response)
if(response._statusCode==200){
alert(response.data);
location.reload();
}
else{
alert("not updated")
}
})
}
Without using location.reload i am not able display updated data
Use $rootscope like this
Add this $rootScope.$emit("refreshData", {});
instead of Location.reload();
And then add this in your main controller for load data without refresh
var RefreshValue = $rootScope.$on("refreshData", function () {
GetValueMethod(); // call your method (List of object) for get data without reload form
});
$scope.$on('$destroy', RefreshValue);
Don't forget to inject $rootScope.

Where should I view Console.log result in AngularJS?

I am having the following code:
var vocabularies = new MyDataService.myService();
vocabularies.success(function (data) {
console.log(data);
}).error(function (data) {
console.log(data);
});
Where can I view the value of data instead of debugging the above code?
If you want to view the data present in the console then you may use keyboard shortcut Ctrl + Shift + J to bring focus on the console.
If you want to see your data during execution you may use alert instead of console.log.
If you want to bind your data to the HTML you need to use
$scope.variable=data;
you can then get your value by using expression tag in HTML.
{{variable}}
You can assign your data to a $scope variable. And on template you can view it. Find below code:
var vocabularies = new MyDataService.myService();
vocabularies.success(function (data) {
console.log(data);
$scope.viewData = data;
}).error(function (data) {
console.log(data);
$scope.viewData = data;
});
And then on the template:
{{viewData | json}}
The above will print it in json format if its json else normal text

Passing the URL/route parameter from laravel and using in angular

I am new to Laravel 5 and angular.
I am using Laravel routing for traversal and backend operations and angular for just UI operations like fetching data and binding UI grid, etc.
I have following route defined in routes.php file below
routes.php
Route::pattern('clientid', '[0-9]+');
//used for AJAX call from angularjs and populating ui-grid
Route::get('getclients/{clientid?}', 'ClientController#getClients');
//used for displaying Laravel view with ui-grid
Route::get('client/{clientid?}', 'ClientController#showClients');
Please find the angular files:
app.js
var appClients = angular.module('getclients', ['clientsService', 'ui.grid', 'ui.grid.exporter', 'ui.grid.selection']);
clientController.js
appClients.controller('ClientsController', ['$scope', '$http', 'Client', '$interval', '$q', function ($scope, $http, Client, $interval, $q) {
/* Defining UI grid options*/
.
.
/* Calling service to fill the grid*/
Client.get(clientid)
.success(function (data, status, headers, config) {
if (data.length > 0) {
$scope.gridOptions.data = data;
}
});
}
clientsService.js
angular.module('clientsService', [])
.service('Client', function ($http) {
return {
// Get all the photos
get: function (clientid) {
if (clientid !== '') {
return $http.get('/myproject/public/getclients/' + clientid);
}
else {
return $http.get('/myproject/public/getclients/');
}
}
}
});
/*
**Note:**
Have already defined route in routes.php for using the same above:
Route::get('getclients/{clientid?}', 'ClientController#getClients');
*/
EXAMPLE:
Step 1:
Say I am hitting URL: http://<domain>/public/myproject/client/2
The following route would catch it and redirect to view where the ui-grid is present
Route::get('client/{clientid?}', 'ClientController#showClients');
Step 2:
Now, somehow need to figure out how to pass that **2** to angular so that I could pass that parameter while making ajax call and get grid data
I am confused as to how we could use the the url parameter from Laravel in angular?
I reckon that I am missing some concept or doing something wrong here.
Could anyone help me out?
Just a workaround to make it work with angular and without jquery.
From routes.php, the control is transferred to showClients action in ClientsController.php
ClientsController.php (Laravel Controller):
Passed the variable to Laravel view from controller using following statement:
public function showClients($clientid = '') {
return view('masters.clients', compact('clientid'));
}
Clients.php (Laravel View)
Added clientidmodel as ng-model and initialized it with passed clientid from Laravel controller using ng-init
<div ng-app="">
<div ng-controller="ClientsController">
<input type="text" name="txtClientId" ng-model="clientidmodel" style="display: none;" ng-init="clientidmodel = '{!!$clientid!!}'"/>
</div>
</div>
clientController.js
Added the watch to the angular model so that we can capture the initial value passed.
$scope.$watch("clientidmodel", function () {
Client.get($scope.clientidmodel)
.success(function (data, status, headers, config) {
if (data.length > 0) {
$scope.gridOptions.data = data;
}
});
});
Not sure whether this is the efficient way but as of now got the things working with this workaround.
Please let me know in case of any better way to approach the same.
You can achieve this in jquery by
var pathname = window.location.href;
var lastItem = pathname.split("/").pop(-1);
Note : Here you will get the last element
i.e.,
If your url is like yourapp.com/app#/product/15 then the script will return 15. That's the last element after / . You can change this according to your wish.
Then you can pass the value directly inside your Laravel Controller.
$.ajax({
type: "POST",
dataType: 'text',
crossOrigin : true,
data: {param : lastItem},
url: serviceUrl+'/getReceipeDetails',
})
.done(function( data ) {
var result = jQuery.parseJSON(data);
if(result.success==1)
{
$(".yourresult").html('Controller return success');
}
else
{
$(".yourresult").html('Controller return failure');
}
})
.fail( function(xhr, textStatus, errorThrown) {
console.log(errorThrown);
});

DOM loading before the promise defer completes

I have a model that I am using to hold my data in angular:
var FuelProcessingModel = function (carrierService) {
this.myArray = [];
};
That model has an array of MyObjects that I get from the DB:
var MyObject = function () {
//stuff
}
I update this using a REST call:
$scope.add = function () {
var myObject = new MyObject();
fuelProcessingService.add(myObject).then(function(result) {
$scope.model.MyObjects.push(result.data);
});
};
Here you can see I want to push the result to the array so that it is added on the screen. But the problem is the DOM loads before that happens.
service to hit the Server:
this.add = function (myObject) {
var deferred = $q.defer();
$http({
method: "POST",
url: "theServer",
data: myObject,
}).success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
The REST service adds to the Database and then returns the updated object
I thought that $q.defer() would cause the DOM to wait to load until the result is returned so that the newly added item shows up.
What am I missing?
UPDATE
I tried doing this but I still have the same problem. The push call is not being called before the DOM loads the page, so the user never sees the added item.
this.add = function (myObject) {
return $http({
method: "POST",
url: "theServer",
data: myObject,
}).success(function (data) {
return data;
});
Html that creates and uses the object
<div ng-repeat="myObject in model.MyObjects" style="margin-bottom: 2%">
//A table of myObjectData
<button class="btn btn-success" ng-click="add()">Add My Object</button>
</div>
Here is what happens in Angular.
Initial html is rendered (also called template html).
Angular boostraps, and then does the necessary binding and the view is updated.
Angular watches for changes and if there is a change in data, view is updated automatically.
When you bind the array to the view the, it renders what is available. When you add some new element to the array later the view should automatically update. You do not need to bother with creating your own promise just do
return $http...

AngularJS - aggregate values from various controllers

I am building an app which aggregates data provided by Facebook GRAPH live. Specifically I want to read the number of likes from various Facebook pages and display a total number of likes. This information is being updated every 5 seconds. I have managed to pull in and update information from individual pages but can not figure out how to add these values together and display the total number. Here is the markup:
<div ng-controller="TotalController">
<span ng-controller="UpdateController" ng-init="init('331288023558058','fan_count')">{{output}}</span>
<span ng-controller="UpdateController" ng-init="init('20531316728','fan_count')">{{output}}</span>
<span>{{outputTotal}}</span>
</div>
and here is the script for it:
var app = angular.module('app', []);
app.controller('UpdateController', function($scope, $http) {
$scope.init = function(id, item) {
$scope.id = id;
$scope.item = item;
//retrieve data on the initial load
$scope.updateData();
};
$scope.updateData = function() {
$http({
method: 'JSONP',
url: 'https://graph.facebook.com/fql?q=select ' + $scope.item + ' from page where page_id = ' + $scope.id + '&callback=JSON_CALLBACK'
}).success(function(data) {
//load the new value
var currentValue = data['data'][0][$scope.item];
//output new value to view
$scope.output = currentValue;
}).error(function(data, status) {
console.log("error " + data + " " + status);
});
};
var timer = setInterval(function() {
$scope.$apply($scope.updateData);
}, 5000);
});
I have tried setting up a controller which encompasses the two Update controllers and watching the scope for changes but I couldn't get the data out of the two child controllers.
My understanding is that the best way to go about it would be to set up a service which aggregates the values, and then inject this service into a third 'Total' controller, but I haven't been able to implement this either. What would be the best way to tackle this problem? Is my approach with controllers completely wrong?

Resources