When try to call function from Controller it doesn't respond - javascript

I'm trying to call a function in my jointController from other javascript file.
var app1 = angular.module('jointApp',[]);
var createStateBox = function(label,color){
var state = new uml.State({
position: {x: 0, y: 0},
size: {width: 200, height: 100},
name: "<<"+label+">>",
events: [label+" box"],
attrs:{rect:{fill:color},path:{"stroke-width":0}}
});
app1.controller('jointController', function($scope) {
$scope.setDecision(state);
alert("This is reached");
});
paper.model.addCell(state);
}
Here is the code in jointMod.js which contains jointController
var app = angular.module('jointApp', []);
function JointController($scope, $http, $filter) {
$scope.list = [];
$scope.newMsg = 'hello';
$scope.newDecision;
$scope.setMsg = function(msg) {
$scope.newMsg = msg;
}
$scope.sendPost = function() {
var data = $.param({
json: JSON.stringify({
msg: $scope.newMsg
})
});
$scope.setDecision = function(decision){
$scope.newDecision = decision;
alert("one two one two")
console.log(decision);
}
$http({
method: 'POST',
url: 'http://213.65.171.121:3000/decision',
data: $scope.newMsg,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
str.push(encodeURIComponent("action") + "=" + encodeURIComponent(obj));
return str.join("&");
}
}).success(function(data, status, header, config) {
$scope.list.push(status);
}).error(function(data, status, header, config) {
$scope.list.push(status);
});
};
};
I have the alert and console log in there to make sure if they can be reach but they do not responed.

The code you provided will not function as you may think. Atleast not if you use both together.
Both codes introduce a new module jointApp and actually only the first one defines a controller. The $scope of that controller is NOT the same of the function in your second code.
If you want to call a method from outside of a controller take a look at events in angular. That would be the best way to archive this. You could also use a dummy object and two-way-bind it (scope: { dummy: '=' }) and then call the method you create on that object in your directive from other code-parts.
Take a look at this plnkr demonstrating both approaches.
http://plnkr.co/edit/YdcB10UpXGqKAxYzXISL?p=preview

Related

Why is my datasource not returning all my data in Angular grid application>?

Let me first preface this by saying...I'm a noob and have been pouring over documentation already but I have not found a resolution.
I have built a custom report in PowerSchool SIS using AngularJS to form my grid and am using JSON data to fill it. The problem I am currently having is the grid is only populating 100 items even though there are close to 200 record items.
This is my JS:
//Begin Module - Loads AngularJS
define(['angular', 'components/shared/index'], function(angular) {
var attApp = angular.module('attApp', ['powerSchoolModule']);
// var yearid = window.location.search.split("=")[1];
//Begin Controller
attApp.controller('attCtrl', ['$scope', 'getData', '$attrs', function($scope, getData, $attrs) {
$scope.curSchoolId = $attrs.ngCurSchoolId;
$scope.curYearId = $attrs.ngCurYearId;
loadingDialog();
$scope.attList = [];
//Sets definition of the var dataSource to pull PowerQueries
var dataSource = {
method: "POST",
url: "/ws/schema/query/com.cortevo.reporting.attendance.absencebymonthschoolgrade",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
data: {yearid},
dataType: "json",
pages:"50",
};
console.log(dataSource);
//Sets definition of the var dataSource to pull from JSON files
console.log('loading dataSource');
//var dataSource= {method: "GET", url: "attendancedata.json"};
getData.getAttData(dataSource).then(function(retData) {
if (!retData.record) {
alert('There was no data returned');
closeLoading();
} else {
console.log(retData);
if (!!retData.record[retData.record.length]) {
// retData.record.pop();
}
var i = retData.record.length;
while (i--) {
retData.record[i].attendance_date = new Date(retData.record[i].attendance_date) // Changes the text of the attendance date to a JS data
}
//Sets scope of attList and attName
$scope.attList = retData.record;
$scope.attName = retData.name;
console.log($scope.attList);
closeLoading();
}
});
}]); //End Controller
//Begins factory and invokes PowerQueries if available, error message will trigger if no data returned
attApp.factory('getData', function($http) {
return {
getAttData: function(dataSource) {
return $http(dataSource).then(function successCallback(response) {
return response.data;
},
function errorCallback(response) {
alert('There was an error returning data');
});
}
}
}); //End Factory
}); //End Module
We have confirmed there is nothing wrong with my datasource. I'm stuck and could use a guiding word. Any advice would be appreciated.
Try to hit the same endpoint using PostMan, maybe the API is not working.
Also I'm not sure if this url is valid:
url: "/ws/schema/query/com.cortevo.reporting.attendance.absencebymonthschoolgrade"

How to call nest factory in Angularjs?

Hi I am developing web application in angularjs. I have requirement below. I have one factory. I have added code snippet below.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', function ($http, $cookieStore, cfg, ScrollFunction, leaselisting) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
leaselisting.leaselisting().then(function (response) {
//Problem in calling
}, function (error) { });
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: "100"
},
headers: ScrollFunction.getheaders()
};
return $http(request);
}
return sadadpaymentapiobject;
}]);
Here is my second factory leaselisting
myapp.factory('leaselisting', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', function ($http, $cookieStore, cfg, ScrollFunction) {
var leaselistingobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
leaselistingobject.leaselisting=function(){
var requestObj = {
url: "api/ServiceRequest/GetROLSPSRLeaseList/",
data: {
LoginID: LoginID,
RSAccountNumber: $cookieStore.get("AccountNumber")
},
headers: ScrollFunction.getheaders()
};
$http(requestObj).then(function (response) {
}, function (error) {
});
}
return leaselistingobject;
}]);
I have found error in below line
leaselisting.leaselisting().then(function (response) { //Problem in calling
}, function (error) { });
May i am i doing anything wrong in the above code? May i know is it possible to call one factory from another? The response i get from leaselisting i want to pass it in callsadad function of sadadpaymentapi. So can someone hep me in the above code? I am getting error Cannot read property 'then' of undefined in the leaselisting.leaselisting().then(function (response) {},function(error){});
Also is there any way I can directly inject factory like payment amount: inject factory something like this?
I assume, that leaselistingobject.getValue is an asynchronous function.
So first of get your value :
leaselistingobject.getValue = function(){
var requestObj = {
url: "api/ServiceRequest/getValue/"
};
return $http(requestObj).then(function (response) {
return response.data;
});
}
And then use it. To let all async actions finish we use angulars $q.Here you can find a small tutorial.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', '$q',function ($http, $cookieStore, cfg, ScrollFunction, leaselisting, $q) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
var leastListingPromise = leaselisting.leaselisting();
var getValuePromise = leaselisting.getValue();
$q.all([leastListingPromise, getValuePromise]).then(function (responses) {
//Here you have both responses in an array
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: responses[1]
},
headers: ScrollFunction.getheaders()
};
return $http(request);
});
}
return sadadpaymentapiobject;
}]);
To make leaselisting() return the response of the request change the end of the function from
$http(requestObj).then(function (response) {
}, function (error) {
});
to
return $http(requestObj).then(function (response) {
return response.data;
}, function (error) {
});
If wont do anything about possible errors you can omit the error function part:
return $http(requestObj).then(function (response) {
return response.data;
});

Why is $scope not working in Angular 1.6.1?

Background
After following the AngularJS tutorial on codeSchool and reading some StackOverflow questions, I decided to start using $scope in order to avoid the hassle of having to define a var self = this; variable.
Problem
The problem is that $scope seems to not be binding anything and nothing works when I use it. I have no idea why, but if I use a var self = this; variable my code will work, even though in theory (according to what I know) $scope should do the same ...
Code
Let's say I have a page where I want to display a big list of numbers. Let's also say I have pagination, and that I want the default amount of Numbers per page to be 4. Let's also assume that after each request to the server, I set the amount of Numbers shown per page to 4 again.
app.js
/*global angular, $http*/
(function() {
var app = angular.module("myNumbers", []);
app.directive("numberFilter", function() {
return {
restrict: "E",
templateUrl: "number-filter.html",
controller: function($scope, $http) {
$scope.filter = {
itemsPerPage: 4
};
$scope.makeRequest = function(numberList) {
console.log("Received submit order");
$http({
method: 'GET',
url: 'https://myNumberServer.com/api/v1/getPrimes',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
numberList= response.data.entries;
$scope.totalPages = response.data.totalPages;
$scope.filter = {itemsPerPage: 4};
console.log("success!");
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
},
controllerAs: "filterCtrl"
};
});
})();
number-filter.html
<form ng-submit="filterCtrl.makeRequest(myNumbers.numberList)">
<div >
<label for="items_per_page-input">Items per page</label>
<input type="number" id="items_per_page-input" ng-model="filterCtrl.filter.itemsPerPage">
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
There are two expected behaviors that should happen and don't:
When I click submit, I should see in the console "Received submit order" and I don't.
The input element should be initialized with 4 when I load the page.
Both of these behaviors will happen if I use the var self = this; trick and replace all mentions of $scope with self.
Questions:
Why is this not working? Am I missing some closure?
You are using controllerAs syntax so when you use that your model needs to be assigned to the controller object itself, not to $scope
Example
controller: function($scope, $http) {
var vm = this; // always store reference of "this"
// use that reference instead of $scope
vm.filter = {
itemsPerPage: 4
};
vm.makeRequest = function(numberList) {
console.log("Received submit order");
$http({
method: 'GET',
url: 'https://myNumberServer.com/api/v1/getPrimes',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
numberList = response.data.entries;
vm.totalPages = response.data.totalPages;
vm.filter = {
itemsPerPage: 4
};
console.log("success!");
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
},

Factory "is not defined" in AngularJS

I'm a beginner in Angular world, and I can't work out why I'm still getting "not defined" error. Here is my code:
angular.module('dopasujApp').factory('getProducts', ['$http', function ($http) {
var dataFactory = {};
dataFactory.sort='ASC';
dataFactory.orderBy='PRODUCT_NAME';
dataFactory.search='a';
dataFactory.filters={};
dataFactory.filters.ATTRIBS=[46,25];
dataFactory.filters.SIZE=[165,40];
getProducts.listProducts = function() {
var request = $http({
method: "POST",
url: "http://******/backend/internalAPI.php?action=getListing&fit=1&limit=10&vendor=20",
headers: {
'Content-Type': 'application/json'
},
data: {
data: dataFactory
}
});
var products = angular.fromJson(request);
return products;
}
return false;
}]);
And here goes my controller (just for testing purposes now).
angular.module('dopasujApp')
.controller('MainCtrl', ['getProducts', '$scope','$rootScope',
function (getProducts, $scope,$rootScope) {
console.log(getProducts.listProducts())
}
]);
getProducts variable in factory is not defined. The name you used before is just informative name for angular
In your factory you are returning "false" as actual result. So angular treats your "false" as result.
It should look like that :
angular.module('dopasujApp').factory('getProducts', ['$http', function ($http) {
var dataFactory = {}, getProducts = {};
dataFactory.sort='ASC';
dataFactory.orderBy='PRODUCT_NAME';
dataFactory.search='a';
dataFactory.filters={};
dataFactory.filters.ATTRIBS=[46,25];
dataFactory.filters.SIZE=[165,40];
getProducts.listProducts = function() {
return $http({
method: "POST",
url: "http://******/backend/internalAPI.php?action=getListing&fit=1&limit=10&vendor=20",
headers: {
'Content-Type': 'application/json'
},
data: {
data: dataFactory
}
});
}
return getProducts;
}]);
Controller
angular.module('dopasujApp').controller('MainCtrl', ['getProducts', '$scope','$rootScope',
function (getProducts, $scope,$rootScope) {
getProducts.listProducts().then(function(res) {
console.log(res.data);
});
}
]);
EDIT:
Also note, that $http returns promise, but not actual query result, updated my example accordingly
try like this
var yourapp = angular.module('dopasujApp', []); //your defining your app first
yourapp.factory('getProducts', function ($http)
{
return {
//write your factory methods
};
});
you controller should be like below
yourapp.controller('MainCtrl', function PostController($scope, getProducts, $compile)
{
//here your controller methods
});

AngularJS: transform response in $resource using a custom service

I am trying to decorate the returned data from a angular $resource with data from a custom service.
My code is:
angular.module('yoApp')
.service('ServerStatus', ['$resource', 'ServerConfig', function($resource, ServerConfig) {
var mixinConfig = function(data, ServerConfig) {
for ( var i = 0; i < data.servers.length; i++) {
var cfg = ServerConfig.get({server: data.servers[i].name});
if (cfg) {
data.servers[i].cfg = cfg;
}
}
return data;
};
return $resource('/service/server/:server', {server: '#server'}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, header) {
return mixinConfig(angular.fromJson(data), ServerConfig);
}
},
get: {
method: 'GET',
isArray: false,
transformResponse: function(data, header) {
var cfg = ServerConfig.get({server: 'localhost'});
return mixinConfig(angular.fromJson(data), ServerConfig);
}
}
});
}]);
It seems I am doing something wrong concerning dependency injection. The data returned from the ServerConfig.get() is marked as unresolved.
I got this working in a controller where I do the transformation with
ServerStatus.get(function(data) {$scope.mixinConfig(data);});
But I would rather do the decoration in the service. How can I make this work?
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service.
I posted the solution to http://jsfiddle.net/maddin/7zgz6/.
Here is the pseudo-code explaining the solution:
angular.module('myApp').service('MyService', function($q, $resource) {
var getResult = function() {
var fullResult = $q.defer();
$resource('url').get().$promise.then(function(data) {
var partialPromises = [];
for (var i = 0; i < data.elements.length; i++) {
var ires = $q.defer();
partialPromisses.push(ires);
$resource('url2').get().$promise.then(function(data2) {
//do whatever you want with data
ires.resolve(data2);
});
$q.all(partialPromisses).then(function() {
fullResult.resolve(data);
});
return fullResult.promise; // or just fullResult
}
});
};
return {
getResult: getResult
};
});
Well, Its actually possible to decorate the data for a resource asynchronously but not with the transformResponse method. An interceptor should be used.
Here's a quick sample.
angular.module('app').factory('myResource', function ($resource, $http) {
return $resource('api/myresource', {}, {
get: {
method: 'GET',
interceptor: {
response: function (response) {
var originalData = response.data;
return $http({
method: 'GET',
url: 'api/otherresource'
})
.then(function (response) {
//modify the data of myResource with the data from the second request
originalData.otherResource = response.data;
return originalData;
});
}
}
});
You can use any service/resource instead of $http.
Update:
Due to the way angular's $resource interceptor is implemented the code above will only decorate the data returned by the $promise and in a way breaks some of the $resource concepts, this in particular.
var myObject = myResource.get(myId);
Only this will work.
var myObject;
myResource.get(myId).$promise.then(function (res) {
myObject = res;
});

Categories

Resources