AngularJS insert data twice to database - javascript

I am trying to insert data to database through angularJS but the data inserted twice.. I have tried to use ngRoute but still I face the same problem.
app.js
var app = angular.module("addDepApp", []);
app.controller('insertDepCtl', function($scope, $http) {
var isSend = false;
$scope.$on('newuser', function(event, data){
load(true);
});
var load = function(isEvent){
if($scope.$parent.newuser != null){
isSend = true;
}
};
load();
$scope.insertDepartment = function () {
console.log("called insertDepartment");
if (isSend == true){
$scope.newuserSend = {'org_id': $scope.$parent.newuser.org_id, 'dep_name': $scope.department};
$http.post("http://192.168.1.12:8888/XXXX/XXX/insertDep.php/",$scope.newuserSend)
}
}
});
add.html
<body ng-app="addDepApp">
<div class="12u$" ng-controller="insertDepCtl">
<input type="button" value="تسجيل" class="special" id="signup" ng-click="insertDepartment()"/>
</div>
</body>

Remove ng-controller="insertDepCtl" from your html code, your router injects this for you. Right now, you're calling everything twice

I have changed the code to this and now it works fine!!
$scope.insertDepartment = function () {
if (isSend == true) {
var request = $http({
method: "post",
url: "http://192.168.1.106:8888/XXXX/XXX/insertDep.php/",
data: {'org_id': $scope.$parent.newuser.org_id, 'dep_name': $scope.department},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
}
}

Related

unable to use $q and promise

I want to use the variable StatusASof to display data in the inserthtml function as below.
App.controller("SS_Ctrl", function ($scope, $http, $location, $window, $sce, $q) {
var ShiftDetails = [];
function getMAStatusASof(Id) {
var defer = $q.defer();
$http({
method: 'GET',
url: 'http://xx/api/Sxxx/GetMAStatusASof',
params: { Id: Id }
}).then(function successCallback(response) {
StatusASof = response.data;
alert("getMAStatusASof : " + StatusASof); --> Got data from API here in this alert.
defer.resolve(response);
}, function errorCallback(response) {});
}
function insertHtml(dates, ShiftDetails, Id) {
// var promise = getMAStatusASof(Id); promise.then(
var defer = $q.defer();
getMAStatusASof(Id);
alert(StatusASof); --> alert says empty here
defer.resolve();
var Content;
Content = '<table class="clsTable"> <tr> <td rowspan="2">Cases ' + $scope.StatusASof + ' </td> <td rowspan="2">Total</td> ';
for (var i = 0; i <= 6; i++) {
if (i == daySeq - 1) {
Content = Content + '<td colspan="3" style="background-color:red"> {{dates[ ' + i + ']}} </td> ';
}
}
}
but $scope.StatusASof is undefined while displaying the result. Looks like $q.defer is not working for me.
How can I continue the execution of code after getting data only from the getMAStatusASof(Id);
Can somebody help here.
Update
you need to return defer.promise;
function getMAStatusASof(Id) {
var defer = $q.defer();
$http({
method: 'GET',
url: 'http://xx/api/Sxxx/GetMAStatusASof',
params: { Id: Id }
}).then(function successCallback(response) {
StatusASof = response.data;
alert("getMAStatusASof : " + StatusASof); --> Got data from API here in this alert.
defer.resolve(StatusASof);
}, function errorCallback(response) {
deferred.reject(false);
});
return defer.promise;
}
and the you can use this function like :
getMAStatusASof(Id).then(function(res){
if(res){
$scope.StatusASof = res;
}
})
No need to use $q.defer() here...
Just do
function getMAStatusASof(Id) {
return $http({
method: 'GET',
url: 'http://xx/api/Sxxx/GetMAStatusASof',
params: { Id: Id }
})
.then(function successCallback(response) {
return response.data;
})
.catch(function errorCallback(response) {
return null; //Effectively swallow the error an return null instead.
});
}
Then, use
getMAStatusASof(Id).then(function(result) {
console.log(result);
});
//No .catch, as we've caught all possible errors in the getMAStatusASof function
If you really would like to use $q.defer(), then the function would need to return defer.promise, like Jazib mentioned.
But as I said, since $http already returns a promise, doing the whole $q.defer() + return defer.promise thing is superfluous.
Instead, use that construction only when the thing you need to wrap isn't returning a promise on its own. E.g when you open a bootbox modal and want to be informed of when the user clicked the close button
function notifyMeOfClosing() {
var deferred = $q.defer();
bootbox.confirm("This is the default confirm!", function(result){
if(result) {
deferred.resolve();
}
else {
deferred.reject();
}
});
return deferred.promise;
}
Unable to update #Daniël Teunkens post with following code(from "}" to ")"). So adding as new answer.
getMAStatusASof(Id).then(function(result) {
// your code here. your HTML content.
....
console.log(result);
})
It will work hopefully.

Call a function to update some variables

I have a collection lines i get from ajax call and i use ng-repeat and for each item line the property line.date need some modification before to be displed
the problem is that I don't know how to call the function to make the modification ?
I try data-ng-init and ng-init the function is called but the variables are not updated !
Html code
<div ng-controller="lineController" data-ng-init="loadLines()">
<div ng-repeat="line in lines">
...
<div data-ng-init="loadDates(line.date)">
...
{{ leftDays}}
</div>
</div>
</div>
Js code :
var app = angular.module("searchModule", []);
app.controller("lineController", function ($scope, $http)
{
// LOAD LINES AJAX
$scope.loadLines = function () {
$http({method: 'GET', url: '..'}).success(function(data) {
angular.forEach(data.content, function(item, i) {
$scope.lines.push(item);
});
});
};
$scope.loadDates = function (date) {
// complex updating of date variable
....
$scope.leftDays = ...;
};
});
Why not manage each line in you angular.forEach?
Like this :
$http({method: 'GET', url: '..'}).success(function(data) {
angular.forEach(data.content, function(item, i) {
//Do stuff to item here before pushing to $scope.lines
//item.date = new Date(item.date) blah blah
$scope.lines.push(item);
});
});
If, you want line.date to be displayed in a different way in you html, and dont want to modify the actual data, why not use a $filter for that?
Like this :
<span ng-repeat="line in lines">{{line.date|yourCustomFilter}}</span>
I think you don't need to do this in this way. You can do this as follows;
$scope.loadLines = function () {
$http({method: 'GET', url: '..'}).success(function(data) {
angular.forEach(data.content, function(item, i) {
$scope.lines.push(item);
});
$scope.lines.map(function(line) {
// here is to modify your lines, with a custom
line.date = $scope.loadDates(line.date);
return line;
})
});
};
By the way, I think you can modify your ajax loading function with this;
$scope.loadLines = function () {
$http({method: 'GET', url: '..'}).success(function(data) {
$scope.lines = data.content.map(function(line) {
// here is to modify your lines, with a custom
line.date = $scope.loadDates(line.date);
return line;
})
});
};
And if you don't need to use loadDates function in view, you don't need to set this function to $scope. You can set this function with just var. Then you can use that function like; loadDates(...) instead of $scope.loadDates(...).
If you don't have to update that $scope.lines variable, you don't need to use .map for this. You can update that function as follows;
$scope.loadLines = function () {
$http({method: 'GET', url: '..'}).success(function(data) {
$scope.lines = data.content;
angular.forEach($scope.lines, function(line) {
// here is to modify your lines, with a custom
$scope.loadDates(line.date);
})
});
};

Not able to obtain value in view (directive)

I have an array in the profile-form.html directive's controller.
But I am neither able to obtain the value of that array (all_languages) nor iterate over it using ng-options in the directive. It's simply printing as string. I am new to Angular and maybe doing everything terribly wrong.
Directive
app.directive("profileForm", function() {
return {
restrict: "E",
templateUrl: "/static/translatorNgApp/profile-form.html",
controller: ['$scope','$http',function($scope, $http) {
this.getCookie = function(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
console.log(cookieValue);
return cookieValue;
};
$scope.csrftoken = this.getCookie('csrftoken');
$scope.myForm={};
$scope.all_languages = ['English', 'Hindi'];
$scope.language_pairs = [];
$scope.getAllLanguages = function () {
$http.get('/getAllLanguages'
).success(function(response) {
// success
$scope.all_languages.concat(response);
}).error(function(response) {
// failed
});
};
$scope.submitForm = function() {
var postData = {
method: 'POST',
url: '/accounts/tprofile/',
// headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
headers: {'X-CSRF-Token' : $scope.csrftoken },
data: $scope.myForm
};
$http(postData)
.then(function(response) {
// success
},
function(response) { // optional
// failed
});
console.log("Form submitted");
// $scope.message = "Sent Successfully 2";
// console.log(postData);
console.log(postData);
console.log($scope.myForm);
};
$document.ready(function(){
console.log("document ready");
$scope.getAllLanguages(); //This can be commented out for the question's sake.
});
}],
controllerAs: "profileFormCtrl"
};
});
Directive Template (profile-form.html)
<div class="form-group" >
<label for="id_source_language">Source language: </label>
<ul>
<li>
<pre>all_languages = {{all_languages | json}}</pre>
<select data-ng-model="source" ng-options="language for language in all_languages" class="form-control" id="id_source_language" name="source_language" placeholder="Source Language" required>
</select>
<button ng-click="language_pairs.pop($index)" aria-label="Remove">Remove</button>
<button ng-click="language_pairs.push({})">Add more pair</button>
</li>
</ul>
</div>
Using document.ready event inside a angular directive doesn't make sense to call specific method of scope. Because document.ready event has already happened after that event only angular started process page.
Ideally to make your code working state you need to remove $document.ready(function(){ .... }); code which isn't required there. And as document.ready is already accomplished, so the one which you had registered from directive wouldn't get call.

Prevent ng-repeat until request data is fully loaded

Im trying to prevent ng-repeat runs before the request data is fully loaded into an array, I've done it using a timeout but it only works when the request takes less than I say
Here is my HTML:
<div class="blocks-container" ng-init="loadProjects()" ng-controller="buildMonitorController">
<div class="row">
<!-- <div> -->
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-2 block animate"
ng-if="!errorDialogActive && finishedRequest"
ng-repeat="build in builds.builds.build track by build._id | orderBy:'lastBuildDetails.startDate' : true"
ng-class="{'running': project.running ,'block-green': build._status ==='SUCCESS','block-red': build._status==='FAILURE'}"
id="{{build._id}}">
<div class="title-container"><p>{{build._buildTypeId}}</p></div>
<div class="update-container col-xs-12">
<time>{{ build.lastBuildDetails.startDate | date : 'dd.MM.yyyy H:mm:s'}}</time>
</div>
</div>
<!--</div>-->
</div>
<!-- Start error state dialog -->
<div ng-include src="'views/main/error-dialog.html'"></div>
And Here is my AngularJS:
$scope.refreshBuilds = function () {
$scope.errorList.length = 0
//#TODO remove this part right after the API is working
//Init
var suffix = '';
var randomnumber = Math.floor(Math.random() * 3);
//simulate mock by random number
switch (randomnumber) {
case 1:
suffix = '-success';
break;
case 2:
suffix = '-less';
break;
default:
break;
}
var url = 'mock/builds'+suffix+'.xml';
console.log('url: ' + url)
$http({
method: 'GET',
url: url,
headers: {
Authorization: 'Basic AAA'
}
}).success(function (data, status) {
//Recive builds from xml and reset scope
var buildsToFilter = new X2JS().xml_str2json(data);
$scope.errorDialogActive = false;
//filter builds which have a no build API detail status
if (buildsToFilter.builds.build !== undefined) {
angular.forEach(buildsToFilter.builds.build, function (build, index) {
$http({
method: 'GET',
url: 'mock/build-'+build._id+'.xml',
headers: {
Authorization: 'Basic AAA'
}
}).success(function (buildDetailData) {
$scope.errorDialogActive = false;
//push detail data into build array
buildsToFilter.builds.build[index].lastBuildDetails = new X2JS().xml_str2json(buildDetailData).build;
console.log(buildsToFilter.builds.build[index]);
}).error(function (data, status) {
$scope.errorDialogActive = true;
//remove build from index if no build detail was found
buildsToFilter.builds.build.splice(index, 1);
$scope.setError(status, '', '');
}).then(function () {
//after filtering builds to display, setup builds $scope for FrontEnd
$scope.builds = buildsToFilter;
});
});
} else {
}
}).error(function (data, status) {
//active dialog if error happens & set error
$scope.errorDialogActive = true;
$scope.setError(status, 'builds', '');
}).then(function () {
$timeout(function () {
$scope.finishedRequest = true;
}, 5000);
//refresh right after proceed and a little delay
$timeout(function () {
console.log('Starting refresh');
$scope.refreshBuilds();
}, 21000);
})
};
You can put condition
ng-show=builds.builds.build.length > 0
So when the builds.builds.build have data then only it will be displayed
You already have that
ng-if="!errorDialogActive && finishedRequest"
in place, but you never set $scope.finishedRequest = false. What if you simply modify your refreshBuilds function like this:
$scope.refreshBuilds = function () {
$scope.finishedRequest = false;
$scope.errorList.length = 0;
// etc
Does it work then in the way you wanted?

How to avoid data mix between $scope variables in ng-repeat when it is broadcasted in other controller?

I have two controllers. In one controller I am storing the data in scope variable for different categories and for different weeks and days. Here is the function for the same:
$scope.fetchWeekList = function(type) {
$scope.loading = true;
var paramtype = (type == 'mo')?'Mobiles':((type == 'ta')?'Tablets':((type == 'la')?'Laptops':'TVs'));
var weekListUrl = url + "/" + paramtype;
var request = $http({
method: "GET",
url: weekListUrl,
headers: { 'Accept' :'application/json','Content-Type' :'application/json', 'Accept-Language': 'en'}
});
request.success(
function(data) {
$scope.weekList = data.object;
$scope.loading = false;
});
request.error(
function(data, status) {
console.log(status);
$scope.weekList = data || "Request failed";
$scope.loading = false;
});
};
Please pat attention that I am fetching the data for the week lists for all the categories with this single function.
Then I am using this:
$scope.$on('fetchSaleDetails', function(event,type) {
$scope.fetchWeekList(type);
}
Then I am broadcasting it in the other controller like this:
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
But when I switch the company the weeks of one category appears in the other and when I click again on the company the data changes. This is the function to update company.
$scope.updateCom = function(corresCom) {
$("html, body").animate({scrollTop: 0 }, "slow");
$rootScope.$broadcast('updateComDetail',corresCom);
$rootScope.$emit('fetchSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
$scope.selectedCom = corresCom;
};
I would be grateful if someone can tell me the issue here. I have tried my best but no luck.
Thanks.

Categories

Resources