Retrive value from JSON using service in AngularJS? - angularjs

I'm a beginner in AngularJS. I'm here trying to fetch the data from JSON using service and display it. I'm having separate files for controllers, services. I'm unable to find out what I'm doing wrong here. I learned that we return an object in case of factory but, I'm not sure how to return the value when using services. The code that I tried is below.
HTML: I have an index.html file into which I load this HTML:
<div ng-controller="comp">
{{capcino}}
</div>
Controller:
var app = angular.module("retailapp");
app.controller("comp", function($scope, elecservice){
$scope.capcino = elecservice.getval();
});
Service:
angular.module("retailapp").service("elecservice", serjson);
function serjson($http){
var val = "";
this.getval = function(){
$http.get("/elec.json").success(function(res){
val = res.namet;
return val;
});
}
}
Routing:
var app = angular.module("retailapp", ['ngRoute']);
app.config(function($routeProvider){
$routeProvider.when("/computer", {
templateUrl : "computer.html",
controller : "comp"
});
JSON:
{"namet" : "naysan"}
I want to display the value "capcino" in expression in HTML. I'm getting undefined for that value. Kindly help with explanation. Thanks in advance.

Write as follow:
var app = angular.module("retailapp");
app.controller("comp", function($scope, elecservice){
elecservice.getval().then(function(data){
$scope.capcino = data;
});
});

It's a promise so it sets $scope.capcino after it returns. Until that return occurs $scope.capcino is undefined.
var app = angular.module("retailapp");
app.controller("comp", function($scope, elecservice){
elecservice.getval().then(function(data){
$scope.capcino = data;
});
});

Just change your controller to store the data.
$scope.yourFunc = function(params){
YouService.function(params).then(function(result){
$scope.yourVar = result.data;
}
})
}
}

Related

Firebase loading $scope view enter doesn't load

I have a loading problem in Firebase. I want to display a list of images when I open the view but nothing happens till i go back ( there is a flash and i can see my photo list). It's working but not displaying in the opening.
What am i missing please ?
There is the beginning of my Controller view:
'Use Strict';
angular.module('App').controller('valider_photosController', function($scope, $state, $localStorage, Popup, Firebase, $firebaseObject, $ionicHistory, $ionicPopup, $ionicModal, $cordovaCamera) {
$scope.imagestab = [];
var ref_logements = firebase.database().ref('logements');
var ref_images = firebase.database().ref('images');
ref_logements.child(id_logement).child('images').on('child_added', added);
function added(idxSnap, prevId){
ref_images.child(idxSnap.key).once('value', function(datasnap){
var bidule = datasnap.val();
bidule['key'] = datasnap.key;
$scope.imagestab.push(bidule);
console.log('La valeur'+datasnap.key+'donne '+datasnap.val());
});
};
});
Since firebase works with asynchronous calls, by the time firebase responds with your data the angular cycle had already finished and you won't have your scope updated. You can force it by using $scope.$apply();.
ref_images.child(idxSnap.key).once('value', function(datasnap){
var bidule = datasnap.val();
bidule['key'] = datasnap.key;
$scope.imagestab.push(bidule);
$scope.$apply();
});
There is a tool that integrates angular and firebase in a way that you won't have to be concerned with things such as applying the scope. Its called angularfire. I totally recommend you to start using it in your application.
With angularfire you can get your data simply using
$scope.bidule = $firebaseObject(ref_images.child(idxSnap.key));
or
$scope.images = $firebaseArray(firebase.database().ref('images'));
I created a Factory
.factory('Firebase', function ($firebaseArray, $firebaseObject) {
var ref = firebase.database().ref();
return {
all: function (section) {
var data = $firebaseArray(ref.child(section));
return data;
},
getById: function (section, id) {
var data = $firebaseObject(ref.child(section).child(id));
return data;
},
get: function (section, field, value) {
var data = $firebaseArray(ref.child(section).orderByChild(field).equalTo(value));
return data;
}
};
})
And then in my controller, i replaced like you said :
var ref_logements = firebase.database().ref('logements');
var ref_images = firebase.database().ref('images');
ref_logements.child(index2).child('images').on('child_added', added);
function added(idxSnap, prevId) {
var monimage = Firebase.getById('images', idxSnap.key);
$scope.imagestab.push(monimage);
};
And it Works like a charm ! Thank you again :)

Read Data From Angular JS Promise Got From ng-ressource

I'm trying to read the following fields (LocationID ..) that I can see in the console when I wrote
console.log($scope.businessInformation);
Console photo capture
Can you help me please?
Thanks
Script.js
app.controller('ProfileController', ['$scope', function($scope) {
$scope.dropLink = '1';
$scope.dropContentLink = '1';
}]);
app.factory('infoService', ['$resource', function($resource){
return $resource('/api/business-information/:id');
}]);
app.controller('BusinessInfoController', ['$scope', 'infoService', function($scope, infoService) {
$scope.isActive = 1;
$scope.is_active_label = 'Active';
$scope.getInfo = function() {
$scope.businessInformation = infoService.query({id: $scope.businessInformation.industryID});
console.log($scope.businessInformation);
};
$scope.updateLabel = function(){
if($scope.isActive === 1){
$scope.is_active_label = 'Active';
}else {
$scope.is_active_label = 'Not Active';
}
};
}]);
routes/api.js
router.route('/business-information/:id')
.get(function(req, res){
conn.query('CALL Inductry_Location_Get(?)', [req.params.id],function(err,info){
if(err) res.send(err);
console.log('Data received from Db:\n');
console.log(info[0]);
return res.send(info);
});
}) ;
module.exports = router;
$resource is awesome because when you call an action like query, the object you receive back will be auto populated as soon as the promise resolves. The problem here is you try to log it right after calling it before the promise gets resolved.
If you want to use it from your controller, you can add your code to the promise which is a property $promise
$scope.getInfo = function() {
$scope.businessInformation = infoService.query({
id: $scope.businessInformation.industryID
});
$scope.businessInformation.$promise.then(function(data) {
// Access data parameter or
console.log(data);
// Use $scope.businessInformation directly since its populated at this point
console.log($scope.businessInformation);
});
};
If you are wanting to use it on your view, you can use the $resolved parameter to know if the data is ready yet.
<div ng-show="businessInformation.$resolved">{{ businessInformation }}</div>
I also want to point out an oddity which is you using $scope.businessInformation before the query is even run. You pass $scope.businessInformation.industryId into the query params.

angularJS controllers and PDF

I work with angularJS and I have some difficulties with controllers.
I have one page on on this page I have two controllers one to receive data from a web service and one to display the data on pdfViewer.
My idea is to start the second controller after the first controller have receive the datas because now it's seems that the two controller start at the same time so nothing is display.
Here my code for the view :
var seeCv = angular.module('myApp', ['ngPDFViewer']);
seeCv.controller('TestCtrl',function($http){
$http.get('some url').success(function(data){
datas = data;
});
});
seeCv.controller('VisuCvCtrl',['$scope','PDFViewerService',function($scope,pdf){
$scope.pdfURL = datas;
$scope.instance = pdf.Instance("viewer");
$scope.nextPage = function(){
$scope.instance.nextPage();
};
$scope.prevPage = function(){
$scope.instance.prevPage();
};
$scope.pageLoaded = function(curPage, totalPages){
$scope.currentPage = curPage;
$scope.totalPage = totalPages;
};
}]);
<div ng-controller="TestCtrl" >
<div class="container" ng-controller="VisuCvCtrl">
<button ng-click="prevPage()"><</button>
<button ng-click="nextPage()">></button>
<br>
<span>{{currentPage}}/{{totalPage}}</span>
<br>
<pdfviewer src="{{pdfURL}}" on-page-load='pageLoaded(page,total)' id="viewer"></pdfviewer>
</div>
</div>
PS: I tried to make the web service call on the second controller but there was a error with the $http.
Each controller has its own scope, you are trying to reach testController scope from VisuCtrl, actually you are trying to use parent's controller scope from child controller. You can do it this way:
seeCv.controller('TestCtrl',function($http){
$http.get('some url').success(function(data){
datas = data;
});
});
seeCv.controller('VisuCvCtrl',['$scope','PDFViewerService',function($scope,pdf){
$scope.pdfURL = $scope.$parent.datas;
...
}]);
Anyhow, I suggest a service in order to fetch the data (This way you can reuse the service get function in others controllers as well).
Controller will use the service to get the data and put it on scope so the view can use this data.
I found a way to do it in the same controller :
seeCv.controller('VisuCvCtrl',['$scope','$http','PDFViewerService',function($scope,$http,pdf){
var promise = $http.get('some url').success(function(data){
datas = data;
});
promise.then(
function(display){
$scope.pdfURL = datas;
$scope.instance = pdf.Instance("viewer");
$scope.nextPage = function(){
$scope.instance.nextPage();
};
$scope.prevPage = function(){
$scope.instance.prevPage();
};
$scope.pageLoaded = function(curPage, totalPages){
$scope.currentPage = curPage;
$scope.totalPage = totalPages;
};
});
}]);
But the thing is now I have this kind of error repeating each 10 seconds.
error: [$interpolate:interr] errors.angularjs.org/1.2.9/$interpolate/interr?p0=%7B%7BpdfURL%7D%7D…2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500
at Error (native)
at code.angularjs.org/1.2.9/angular.min.js:6:449
at Object.$get.s (https://code.angularjs.org/1.2.9/angular.min.js:73:497)
at h.Bd.$get.h.$digest (code.angularjs.org/1.2.9/angular.min.js:100:171)
at h.Bd.$get.h.$apply (code.angularjs.org/1.2.9/angular.min.js:103:100)
at HTMLButtonElement. (code.angularjs.org/1.2.9/angular.min.js:179:65)
at code.angularjs.org/1.2.9/angular.min.js:27:208
at q (code.angularjs.org/1.2.9/angular.min.js:7:380)
at HTMLButtonElement.Zc.c (code.angularjs.org/1.2.9/angular.min.js:27:190) angular.js:9419
(anonymous function)
And I really don't know what it is.

Execute scope function from service parameter

I am trying to create a service when I can set my formSubmit.
For example. In controller A I call "service.setFormSubmit(doThis(obj))" and in controller B I call "service.getFormSubmit()". Where it will execute the function doThis(obj) in controller B.
UPDATE - Re-formulated question.
I have 1 view where I want to edit or create a category. This means I need a dynamic ng-submit. I want to to this in the controller. So like this:
$scope.editCategory = function(obj) {
$scope.formSubmit = 'editCategory'
}
And on the create I want to change the formSubmit var to createCategory of course.
So I can make a difference between creating and editing the category.
Is this possible? Would be really nice if someone has a way to do this..!
Thanks in advance!
Instead of passing around strings which need to be eval'ed, use the service to share functionality directly between controllers.
The service can be dirt-simple:
.factory('MyService', function(){
var service = {};
return service;
});
Once injected and assigned to scope variables in both controllers you have an intermediary unit which can act as a modifiable channel for cross-controller collaboration.
.controller('FirstController', function($scope, MyService){
$scope.service = MyService;
})
.controller('SecondController', function($scope, MyService){
$scope.service = MyService;
$scope.service.create = function(obj){
console.log('Creating');
}
$scope.service.edit = function(obj){
console.log('Editing');
}
})
From the scope of FirstController, you can now call the function also available on the scope of SecondController:
<div ng-controller="FirstController">
<input type="checkbox" ng-model="button.type"> Toggle create/edit<br/>
<button ng-if="button.type" ng-click="service.create(obj)">Create</button>
<button ng-if="!button.type" ng-click="service.edit(obj)">Edit</button>
</div>
Demo
If you aren't reloading the page you can create an encapsulated variable in your service. Your set call would assign the value passed to that variable and your get call would return that variable to the caller.
One way I have achieved passing the data is to submit the form using the service and return a Json result to the service. Store the Json object in the encapsulated variable on the return and then pass a success or failure to the controller. When successful, let the controller redirect the view which will redirect using angular routing and ng-view. Once the new view, along with the new controller is loaded into the page, you can call the variable in your service to retrieve the data on the next controller.
Example Code:
app.factory('service', function ($q, $http) {
var savedData;
return {
loadData: function() {
return data;
},
search: function (parameters) {
var searchURL = '/MVCController/Search?parameter1=' + parameters.one +
'&parameter2=' + parameters.two;
var deferred = $q.defer();
$http.get(searchURL).success(function (data) {
savedData = data;
deferred.resolve(true);
}).error(function(data) {
data = 'An error occurred while searching: ' + data;
savedData = data //(if you want to save the error)
deferred.reject(data);
});
return deferred.promise;
}
}
});

Better design for passing data to other ng-view's and persisting it across controllers

I started developing in AngularJS. I'm confused as to whether this is a proper design to pass data between my partial views.
Right now I have a loader page where I do some request.
function PeopleController($scope,$http,$location){
$http.get('/location/-79.18925/43.77596').
success(function(data){
$scope.savePeopleResponse(data);
$location.url('/test');
});
}
Then in the view that gets loaded for /test
I am just calling
<div ng-controller="resultController">
<div class="blueitem">{{getResultForPeople()|json}}</div>
</div>
[resultController]
function resultController($scope){
$scope.getResultForPeople = function(){
return $scope.getPeopleResponse();
}
}
and the savePeopleResponse and getResultForPeople are "cached" in the rootScope as such
app.run(function($rootScope) {
var peopleResponse = {};
$rootScope.savePeopleResponse = function(data) {
peopleResponse = data;
console.log(data);
}
$rootScope.getPeopleResponse = function(){
return peopleResponse;
}
});
Now as you can see, this will get very messy if this application grows larger and larger. What's the best way to handle data so that it's persisted across controllers?
You can persist data across controllers by creating your own service as described nicely in this blog. You can also refer to this question.
In your case you can move your savePeopleResponse and getPeopleResponse into a service and then inject the service into any controllers you would like to access it.
angular.module('myApp', [])
.factory('peopleService', function () {
var peopleResponse = {};
return {
savePeopleResponse:function (data) {
peopleResponse = data;
console.log(data);
},
getPeopleResponse:function () {
return peopleResponse;
}
};
});
With your controller something like this:
function resultController ($scope, peopleService) {
$scope.getResultForPeople = peopleService.getPeopleResponse;
}
With this code example make sure you include ng-app="myApp"

Resources