AngularJS call Rest Api: TypeError - angularjs

I am calling restful service from AngularJS. HTML is very basic with a input text box and a button for query.
// basic.html
<!DOCTYPE html>
<html ng-app="cgApp" >
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-resource.js"></script>
<script src="../js/controller.js"></script>
<script src="../js/service.js"></script>
</head>
<body>
<div ng-controller="CgseqCtrl">
<input ng-model="analysisid"><button ng-click="searchById()">Search</button>
<table>
<tr>
<td>{{seq.analysisId}}</td>
<td>{{seq.center}}</td>
<td>{{seq.diseaseAbbr}}</td>
<td>{{seq.filepath}}</td>
<td>{{seq.library}}</td>
</tr>
</table>
</div>
</body>
</html>
I use a service to call rest api
// service.js
app.factory("Cgseq", function ($http) {
// return $resource('http://localhost:8080/cgweb/api/seqs/fdebfd6e-d046-4192-8b97-ac9f65dc2009');
var service = {};
service.getSeqById = function(analysisid) {
return http.get('http://localhost:8080/cgweb/api/seqs/' + analysisid);
}
service.getSeq = function() {
return $http.get('http://localhost:8080/cgweb/api/seqs/fdebfd6e-d046-4192-8b97-ac9f65dc2009');
}
return service;
});
The function searchById() will be executed once the button is clicked. It is implemented in my controller.
// controller.js
var app = angular.module('cgApp', [])
app.controller('CgseqCtrl', ['$scope', 'Cgseq', function($scope, Cgseq){
$scope.searchById() = function() {
CgSeq.getSeqById($scope.analysisid)
.then(function(response){
$scope.seq = response;
});
}
}]);
When I load basic.html in a browser, even before I type in something in the input box and click the button, I got the following error:
angular.js:12416 TypeError: $scope.searchById is not a function
at new <anonymous> (controller.js:8)

You should remove the () from $scope.searchById() = function
And correct the typo (case-sensitivity) for Cgseq
I.e.:
$scope.searchById = function() {
Cgseq.getSeqById($scope.analysisid)
.then(function(response){
$scope.seq = response;
});
}

Related

Passing data from one route to another route

It must be able to pass data between route controllers. Like for example have an input field in one route where its contents will be displayed in the next route. I don't want it with $rootScope.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "John Doe";
});
</script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="name">
<h1>You entered: {{name}}</h1>
Click to see this data to another page (route)
</div>
</body>
</html>
See This
RipTutorial -
Handling session storage through service using angularjs
app.factory('storageService', ['$rootScope', function($rootScope) {
return {
get: function(key) {
return sessionStorage.getItem(key);
},
save: function(key, data) {
sessionStorage.setItem(key, data);
}
};
}]);
app.controller('myCtrl',['storageService',function(storageService) {
// Save session data to storageService
storageService.save('key', 'value');
// Get saved session data from storageService
var sessionData = storageService.get('key');
});

AngularJs with REST Api

i'm new to angularJs and want to learn more about it, i'm trying to display some users from a fake REST Api, when trying to run my code i got empty page and the console doesn't give me any errors , i don't know where is the error or where i can debug.
app.js
var myApp = angular.module("app", []);
contactsData.service.js look like that :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http) {
var self = this;
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
var promise2 = promise1.then(function (response) {
return response.data;
});
return promise2;
}
});
})();
contacts.controller.js
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl(contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
this.contacts = data;
});
}
})();
finally my view index.html
<html ng-app="app">
<head>
<title></title>
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="contacts.controller.js"></script>
<script src="contactsData.service.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" />
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
</head>
<body class="container">
<div>
<div ng-controller="contactsCtrl as ctrl">
<div class="raw">
<ul class="list-group">
<li class="li-group-item" ng-repeat="obj in ctrl.contacts">
{{obj.name.title + " " + obj.name.first + " " + obj.name.last}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
Small correction required in your contactsCtrl
function contactsCtrl(contactDataSvc) {
var vm = this;
contactDataSvc.getContacts()
.then(function(data){
vm.contacts = data;
});
}
You cannot use this inside the then callback as the scope will be different.
Corrected working example here : http://plnkr.co/edit/LLKJipkBbiZ17QjQpw1X
Refer more:
https://www.w3schools.com/js/js_scope.asp
What is the scope of variables in JavaScript?
1 - Is this url correct? http://localhost:3000/contacts
2 - Open the url on any browser, does it return any response ? JSON?
Please check this first to see if the problem is not on the server side.
Firstly inject $scope in controller because anything/data that we want to access over Html from controller needs to be binded on $scope.
So you controller would look like:
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl($scope,contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
$scope.contacts = data;
});
}
})();
Secondly from the service you need to return a promise from it only then you will be able to get the data once the response is back from the API.
So,the updated service code is :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http,$q) {
var self = this;
var defered = $q.defer();
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
promise1.then(function (response) {
defered.resolve(response.data);
});
return defered.promise;
}
});
})();

AngularJs dependency injection related to $http

While writing the above code in AngularJs, I am getting an error :
Error: $injector:unpr
Unknown Provider
Unknown provider: $http
I believe the reason might be while injecting $http through the serviceProvider which in my case is httpServiceProviderFunction.$inject = ["$http"];. I would appreciate if anyone could help me understand these two questions:
1) Although I have injected the $http in the httpServiceProviderFunction. Why am I getting the above error?
2)Is there any way I can inject $http in the service directly without injecting in serviceProvider? In my example, it corresponds to this line:
function httpService(url, $http) {.....}
The code snippet can be found below:
(function() {
angular.module("httpServiceApp", []).controller("httpServiceController", httpServiceControllerFunction).provider("httpService", httpServiceProviderFunction).config(configObj);
configObj.$inject = ["httpServiceProvider"]
function configObj(httpServiceProvider) {
httpServiceProvider.configuration.baseUrl = "http://davids-restaurant.herokuapp.com/categories.json";
}
httpServiceProviderFunction.$inject = ["$http"];
function httpServiceProviderFunction($http) {
var provider = this;
provider.configuration = {
baseUrl: "http://davids-restaurant.herokuapp.com/categories.json"
}
provider.$get = function() {
var service = new httpService(provider.configuration.baseUrl, $http);
return service;
}
}
function httpService(url, $http) {
var service = this;
service.menuCategories = function() {
var response = $http({
method: "GET",
url: url
});
return response;
}
}
httpServiceControllerFunction.$inject = ["httpService"]
function httpServiceControllerFunction(httpService) {
var service = httpService;
var controller = this;
var promise = service.menuCategories();
promise.then(function(response) {
controller.categories = response.data;
}).catch(function(error) {
console.log("Error occured", error);
})
}
})();
<!DOCTYPE html>
<html ng-app="httpServiceApp">
<head>
<meta charset="utf-8">
<meta name="description" content="First Angular App">
<meta name="keywords" content="HTML, Javascript, AngularJs">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.angularjs.org/1.6.1/angular.min.js"></script>
<script src="app1.js"></script>
<title>HTTP service in AngularJs</title>
</head>
<body>
<div ng-controller="httpServiceController as controller">
<div>
<ul>
<li ng-repeat="items in controller.categories">({{items.short_name}}){{items.name}}</li>
</ul>
</div>
</div>
</body>
</html>
Thank you for your time. I appreciate your help.

Wait for async data before rendering a list on AngularJS and Ionic

I am a newbie on Angular JS but have good experience working with Javascript.
In my App I am creating a simple Factory fulfilled by JSON data coming from a web service:
.factory('Tools', function($http) {
var tools = {content:null};
var promise = $http.get('/Tool/GetTools').success(function(data) {
tools.content = data;
//At this points all the data is on tools.content
});
return {
promise:promise,
all: function(){
return tools;
//At this point tools equals to null
}
}
});
But when I want to render the list:
<ion-list>
<ion-item ng-repeat="tool in tools">
Hello, {{tool}}!
</ion-item>
</ion-list>
The info isn't still there yet.
I have this on my controller:
.controller('AccountCtrl', function($scope, Tools) {
$scope.tools = Tools.all();
});
Is there a way to tell the list to "wait" while the Tools object loads from the ajax call before the list renders?
Thanks!
You have to return from your factory the promise and into controller you can check the success.
Something like this:
(i've simulated the wait with a timeout)
angular.module('App', [])
.controller('Ctrl', function($scope, resultsFactory) {
$scope.results = [{txt: 'Loading..'}];
resultsFactory.all().then(
function(res){
$scope.results = res;
},
function(err){
console.error(err);
}
);
})
.factory('resultsFactory', function($http, $timeout, $q) {
var results = {};
function _all(){
var d = $q.defer();
$timeout(function(){
d.resolve([{txt:'one'},{txt:'two'},{txt:'three'}]);
}, 2000);
return d.promise;
}
results.all = _all;
return results;
});
<!DOCTYPE html>
<html ng-app='App'>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.20/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div ng-controller='Ctrl'>
<p ng-repeat='res in results'> {{res.txt}}</p>
</div>
</body>
</html>
You have to say {{tool}}
Its typo :-)
<ion-list>
<ion-item ng-repeat="tool in tools">
Hello, {{tool}}!
</ion-item>
</ion-list>

Use scope from multiple controllers on page

So i've split out my UI into subcomponents but then i realise that one of the components requires to be react to a dropdown change which is caught by the parent controller.
I can create a shared service for the variables and i have been able to inject the sub controller so that i can kick off functions BUT.
how do i then use the scope within the sub controller?
var ctrl1= $scope.$new();
$controller('ctrl', { $scope: ctrl1});
ctrl1.GetData();
this works fine. I can see data coming back in the console. BUT my ui doesnt change. What am i missing?
I've edited the post to illustrate what i'm attempting to do more clearly.
The drop down on change is caught by the parent controller but i then require the child controller to run away and get some data and update the UI.
It's an attempt to split out the components. Is this possible? Or have a split the components out too far?
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<script>
angular.module('app2', [])
.controller('ctrl2', ['$scope', '$http', function($scope, $http){
$scope.getdata = function(){
$http.post(WebServiceURL)
.success(function(data){
$scope.app2Data = "test2 data";
});
}
}]);
angular.module('app1', ['app2'])
.controller('ctrl1', ['$scope','$controller',function($scope, $controller){
$scope.name = 'Controller 1';
//just something to put in the ddp
$scope.data = [
{id:1, name: "test"},
{id:2, name: "test2"}
]
$scope.makeChanged = function(id){
//ddp has changed so i refresh the ui with some other data which is in got by ctrl2.
var cl2 = $scope.$new();
$controller('ctrl2', { $scope: cl2 });
cl2.getdata();
}
}]);
</script>
</head>
<body ng-app="app1">
<div ng-controller="ctrl1">
<p>here is: {{name}}</p>
<select ng-model="d" ng-options="d as dat.name for dat in data track by dat.id" ng-change="makeChanged(d.id)"></select>
<div>
{{app2Data.text}}
</div>
</div>
</body>
</html>
for anyone interested here's how i got round this.
I created a shared service between the two controllers. and created a callback on the service. i registered the call back on ctrl2 so when the shared variable changed the controller2 will do what i want it to and scope is freshed.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<script>
angular.module('app1', ['app2'])
.controller('ctrl1', ['$scope', '$controller', 'appointmentSharedProperties',
function($scope, appointmentSharedProperties) {
$scope.name1 = 'Controller 1';
console.log('ctrl1');
//just something to put in the ddp
$scope.data = [{
id: 1,
name: 'test'
}, {
id: 2,
name: 'test2'
}];
$scope.makeChanged = function(value) {
//ddp has changed so i refresh the ui with some other data which is in got by ctrl2.
appointmentSharedProperties.setDetail(value);
console.log('in makeChanged: ' + value);
}
}
]).service('appointmentSharedProperties', function() {
var test = '';
var __callback = [];
return {
getDetail: function() {
return test;
},
setDetail: function(value) {
test = value;
if (__callback.length > 0) {
angular.forEach(__callback, function(callback) {
callback();
});
}
},
setCallback: function(callback) {
__callback.push(callback);
}
};
});
angular.module('app2', [])
.controller('ctrl2', ['$scope', 'appointmentSharedProperties',
function($scope, appointmentSharedProperties) {
$scope.name2 = 'Controller 2';
console.log('ctrl2');
var getdata = function() {
console.log('in getdata');
$scope.app2Data = appointmentSharedProperties.getDetail();
}
appointmentSharedProperties.setCallback(getdata);
}
]);
</script>
</head>
<body ng-app="app1">
<div ng-controller="ctrl1">
<p>here is: {{name1}}</p>
<p>here is: {{name2}}</p>
<select ng-model="d" ng-options="d as dat.name for dat in data track by dat.id" ng-change="makeChanged(d.name)"></select>
<div>
{{app2Data}}
</div>
</div>
</body>
</html>
General example of how to pass variables from one controller to other
<html>
<head>
<meta charset="ISO-8859-1">
<title>Basic Controller</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
</head>
<body ng-app="myApp">
<div ng-controller="ctrl1">
{{greeting}}
</div>
<div ng-controller="ctrl2">
{{dataToHtml2}}
</div>
</body>
</html>
This is the javascript file for this
var myApp = angular.module('myApp',[]);
myApp.service('sampleService', function(){
var temp = '';
this.setValue = function(data){
temp = data;
}
this.getValue = function(){
return temp;
}
});
myApp.controller('ctrl1', function($scope,sampleService) {
$scope.greeting = 'This line is in first controller but I exist in both';
var data= $scope.greeting;
sampleService.setValue(data);
});
myApp.controller('ctrl2', function($scope, sampleService){
$scope.dataToHtml2 =sampleService.getValue();
});
Here is the blog that explains this flow : Frequently asked questions in angularjs
It has the demo of what I written. Happy coding..!!

Resources