I am stuck on some problems , actually I was in problem solved , the problem was header which is not enableing to get response (like CORS issue) ,overcome by using header and transformRequest as shown in below code. After that I got webservice data but in one controller used $rootscope which render some of id of data of second method (API) to use in another controller to put on third one api to get data and I am getting this for only a minute then it will throw error : Cannot read property 'companies data' of null which is field in third api. when I used $rootScope.Test.companies[0].companyname which is store data, and unique for all api like primary key.
var request = $http({
method: "post",
url: "http://app.xyz/xyzapp/public/user/login",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
str.push(encodeURIComponent('email_id') + "=" + encodeURIComponent('demo#xyz.com'));
str.push(encodeURIComponent('password') + "=" + encodeURIComponent('demo#xyz'));
return str.join("&");
},
});
request.success(function( response ) {
console.log("Hiiiii::::"+JSON.stringify(response,status));
if (response.status=="success"){
$rootScope.Test1=response.user_id;
var request1 = $http({
method: "post",
url: "http://app.xyz/xyzapp/public/company/getUserCompanyList",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
str.push(encodeURIComponent('user_id') + "=" + encodeURIComponent(response.user_id ));
// str.push(encodeURIComponent('password') + "=" + encodeURIComponent('demo#123'));
return str.join("&");
}
});
// getCompany
request1.success(function( response ) {
console.log("Hiiiii::::"+JSON.stringify(response,status)+" "+response.companies.length+":Length");
if (response.status=="success"){
// alert(1);
$state.go('tabdash');
$rootScope.Test = response;
}
});
So please tell me how to use one controller data to another where I am using another api which will get $rootscope date of parent.
Please let me know if anybody know about that or anything
Thanks
Yes you can use variables of one controller inside another controller using two methods
Create Service to communicate between them.
Use $rootScope.$broadcast
sample code
angular.module('myservice', []).service('msgBus', function() {
this.serviceValue= {};
}]);
});
and use it in controller like this:
controller 1
angular.module('myservice', []).controller('ctrl1',function($scope, msgBus) {
$scope.sendmsg = function() {
msgBus.serviceValue='Hello';
}
});
controller 2
angular.module('myservice', []).controller('ctrl2',function($scope, msgBus) {
$scope.checkValue(){
alert( msgBus.serviceValue);
}
});
Related
Background
I am making Service which has a list to be shared between two controllers. To start I followed this tutorial on Services:
https://thinkster.io/a-better-way-to-learn-angularjs/services
And I managed to successfully create and execute the basic tutorial on Plunker:
https://plnkr.co/edit/niUlaHP54wWpjSoWURNX
Problem
The problem here, is that when I click the form button, I need to make an HTTP GET request to my server, and update the service list when I get the response.
To achieve this, I first tried using the following Plunker modification:
https://plnkr.co/edit/Z7K9CJbNP9LClycRHwBd?p=info
The jest of the code can be seen in the service:
// Create the factory that share the Fact
app.factory('ListService', function($http) {
var list = {};
list.data = [];
list.request = function(theHairColor) {
var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
console.log(theUrl);
$http({
method: 'GET',
url: theUrl,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
list.data = response.data.entries; //does not work
console.log(response.data.entries);
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
return list;
});
If you tried it out, you will see it simply doesn't work, and I don't really understand why. In a previous question I made, someone explained to me that it was related to references, and that I should replace list.data = response.data.entries; //does not work for the following:
//this works but is rather flimsy ....
list.data.length = 0;
Object.assign(list.data, response.data.entries);
Which in deed does work, but I find it rather counter intuitive:
https://plnkr.co/edit/ABdxPI4coNYlJ85EIOJl
Another suggestion was also given, in that I should change my gnomeList controller to :
app.controller("gnomeList", function(ListService) {
var self = this;
self.listService = ListService;
});
and then iterate over the service's list directly:
<div ng-controller="gnomeList as listCtrl">
<p ng-repeat="gnome in listCtrl.listService.data">{{ gnome.id }}: {{ gnome.name }}</p>
</div>
Which also works, but attaches the controller directly to the service:
https://plnkr.co/edit/h48CmupRjRFoxFT5ZSd8
Questions:
Are there any other ways to make my first code sample (that didn't work) work?
Which of these solutions would be preferable and why? (which one is more Angulary?)
Problem is you initially copy the data in your gnomeList and it is passed by value.
app.controller("gnomeList", function(ListService) {
var self = this;
self.list = ListService.data;
});
When your controller gets initialized here, it puts a copy of ListService.data into self.list. However, when updating the values in the services, this controller does not get initialized again and therefore the value is not updated.
Objects in javascript are passed by reference. Just like you said, you could directly put the service on scope to use its data or you simply set the properties on an object before you set them on your scope. (Plunkr)
Javascript
app.controller("gnomeList", function(ListService) {
var self = this;
self.list = ListService.value; // value is an object
});
// Create the factory that share the Fact
app.factory('ListService', function($http) {
var list = {};
list.value = {};
list.request = function(theHairColor) {
var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
console.log(theUrl);
$http({
method: 'GET',
url: theUrl,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
list.value.data = response.data.entries; // extend value object
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
return list;
});
HTML
<div ng-controller="gnomeList as listCtrl">
<p ng-repeat="gnome in listCtrl.list.data">{{ gnome.id }}: {{ gnome.name }}</p>
</div>
Moreover it is better to use built in angular.extend for extending objects.
So this doesn't work?
list.request = function(theHairColor) {
var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
console.log(theUrl);
$http({
method: 'GET',
url: theUrl,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function success(data) {
list.data = data;
console.log(data);
return data;
});
};
That would be a structure we've used in the past (we use Restangular now), but this link is a good page to see about $http that would help you.
I'm working on one project with AngularJs(1.5) and Codeigniter rest server. I'm wondering why data idTag isn't passed to php? Let me show you my code and explain further with comments.
I have this factory
factory.get = function(idLocation, idTag){
console.log(idLocation, idTag); //Console log outputs 1 6, so data is here
return $http({
method: 'GET',
url: $location.protocol() + '://' + $location.host() + '/rest/api/locationtag/locationtag/' + idLocation,
data: {
idTag: idTag
}
}).then(function successCallback(response){
console.log(response);
// response is empty, because data isn't sent to PHP
return response.data;
},function errorCallback(response){
console.log('Error getting slide shows: ' + response.data.message);
});
};
And this is my PHP where i try to fetch the code
public function locationtag_get($idLocation)
{
$condition['id_location'] = $idLocation;
$condition['id_tag'] = $this->get('idTag');
var_dump($condition);
die();
$locationTag = $this->locations_tags->get($condition);
if ($locationTag) {
$this->response($locationTag, REST_Controller::HTTP_OK);
}
}
Out put of var_dump is
'id_location' '1'
'id_tag' null
SO the question, why or how to properly send data from GET method to PHP rest controller in Codeigniter?
If you need any additional information's, please let me know and i will provide. Thank you in advance!
For GET requests you should use params instead of data (which is for POST requests). You can confirm this in the AngularJS documentation.
params – {Object.} – Map of strings or objects which
will be serialized with the paramSerializer and appended as GET
parameters.
Of course, nothing stops you from adding them to the URL but you'd have to deal with encoding the information properly instead of just passing the JSON object.
You should be using a params property in your $http config object:
$http({
url: $location.protocol() + '://' + $location.host() + '/rest/api/locationtag/locationtag/' + idLocation,
data: {,
method: "GET",
params: {idTag: idTag}
});
This will append as query string to you url, which you can then inspect in your server side code.
In my console the error is coming "getIdData is not defined" what is wrong with my code. Here deal is my service and getIdData is my function in service.
$scope.editUserDetail = function editUserDetail(){
$scope.showEditView = !$scope.showEditView;
$scope.showSubmitView = !$scope.showSubmitView;
console.log(deal);
deal.getIdData().then(function successCb(data){
$scope.editIdOptionsData=data;
});
};
Please check working example here: Demo
You are forget to return service object from service.
i.e
Write following code in your service,
return service;
i.e
angular.module('account').service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var service = {};
var baseUrl = account.app.url;
service.getIdData = function(data, accountId, decisionMakerDetail) {
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post',
url: url,
data: data,
def: def
}, function(resp) {
def.resolve(resp.msg);
});
return def.promise;
};
return service;
});
Or as you are using service you can write it using this
angular.module('account').service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var baseUrl = account.app.url;
this.getIdData = function(data, accountId, decisionMakerDetail) {
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post',
url: url,
data: data,
def: def
}, function(resp) {
def.resolve(resp.msg);
});
return def.promise;
};
});
For more information please check - Services
Please clean your browser and inspect source.Look deal.getIdData() is loaded or not.May be it is not loaded.Please load properly.
The object you are sending as a parameter doesn't have the getIdData() function defined.
Change your log to:
console.log(deal.getIdData);
and then check whether it returns the function code/definition.
Here is a link with an example of how implement a factory and service.
Angular factory and service
You are not returning the object holding the service reference from you your service registration function. Change your code as below for it to work.
angular.module('account')
.service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var service = {};
var baseUrl = account.app.url;
service.getIdData = function(data,accountId,decisionMakerDetail){
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post', url: url, data: data, def: def
}, function (resp) {
def.resolve(resp.msg);
});
return def.promise;
};
return service;
});
S8nce you were not returning anything from the service, even though deal service gets registered, its value is undefined and when you try to access deal.getIddata() you get the aforementioned error
Hello guys I really need help and advice on this factory and controller issue I am having.
I have a factory that gets data from the server
sp.factory('homeFeed',['$window','$http','auth',function($window,$http,auth){
var url = auth.url;
var version = auth.version;
var HomeFeed = {};
HomeFeed.getFeeds = function(user){
//setting variable for get request on home feed
var req = {
method: 'GET',
url: url + version + '/Feed',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Bearer ' + token
},
}
return $http(req).success(function(res){
return res;
});
};
return HomeFeed;
}]);
controller--
sp.controller('HomeCtrl',['$scope','homeFeed','$window',function($scope,homeFeed,$window){
//getting all the home feed data
$scope.feeds = homeFeed.getFeeds(JSON.parse($window.localStorage['SP-User']))
}]);
however, after the respond from the server, my view is not updated and the $scope.feeds is not updated as well. Greatly appreciate your help
As you are doing async $http call then that data would not be available at that instance of time. It would be available when ajax call succeeded. You need to use .then function which will create a promise chain and will execute a function when .success function returns a data.
Controller
sp.controller('HomeCtrl',['$scope','homeFeed','$window',
function($scope,homeFeed,$window){
//getting all the home feed data
homeFeed.getFeeds(JSON.parse($window.localStorage['SP-User']))
.then(function(data){
$scope.feeds = data
});
}
]);
I am trying to use POST with $resource object in my app.
I have something like this.
Factory:
angular.module('toyApp').factory('toys', ['$resource', function ($resource) {
return $resource('/api/v1/toy/:id/condition/:condid',
{ id: '#id',
condid: '#condid' }
);
}]);
Controller:
$scope.addNew = function() {
//how do I pass id and condid below?
toys.save({'name': 'my first toy'});
})
The above code will pass url like
/api/v1/toy/condition/
I need to send the request url like
/api/v1/toy/6666/condition/abd with parame {'name': 'my first toy'}
How do I do it?
Thanks for the help!
It's very clearly described in the API reference:
https://docs.angularjs.org/api/ngResource/service/$resource
What $resource(url) returns is a class object. If you want to create a new instance and save it, you'll call the $save method on the instance:
var Toy = $resource('/api/v1/toy/:id/condition/:condid',
{id: '#id', condid: '#condid'});
var toy = new Toy({'id': 123, 'condid': 456, 'name': 'my first toy'});
toy.$save();
But if you want to call an object creation API, you'll have to add a custom method to your resource:
var Toy = $resource('/api/v1/toy/:id/condition/:condid',
{id: '#id', condid: '#condid'},
{createToy: {method: 'POST', url: '/create-toy'}});
Toy.createToy({name: 'Slingshot'});
var newToy = new Toys({id: '6666', condid: 'abd'});
newToy.name = 'my first toy';
newToy.$save();
Try this
$scope.addNew = function() {
toys.save({'id': 'foo', 'condid': 'bar'});
})
You are correct in extrapolating $http controller logic to a service/factory.
Create a method to set the object that you will send with the HTTP POST request. Another method to set the url may also be created. The controller will then call these methods before saving to set the url and object to be used for the HTTP call. A dynamic url may be specified in the controller (with unique id and other fields as necessary) and sent to the service.
Service code:
var dataObj = [];
var myUrl = "";
//called from controller to pass an object for POST
function setDataObj(_dataObj) {
return dataObj = _dataObj;
};
function setUrl(_url) {
return myUrl = _url;
}
function saveToy() {
//if sending a different type of obj, like string,
//add "headers: { 'Content-Type': <type> }" to http(method, url, header)
$http({ method: 'POST', url: myUrl })
.then(function(data) {
return data;
})
.catch(function(error) {
$log.error("http.post for saveToy() failed!"); //if log is added to service
});
};
Controller code:
$scope.id = 574; //or set somewhere else
$scope.condid = 'abd';
$scope.objectYouWantToSend = [{"toyName": "Teddy"}];
// to obtain dynamic url for /api/v1/toy/:id/condition/:condid
$scope.url = '/api/v1/toy/' + $scope.id + '/condition/' + $scope.condid;
$scope.addNewToy = function() {
toyService.setUrl(url); //set the url
toysService.setDataObj($scope.objectYouWantToSend); //set the dataObj
toysService.saveToy(); //call the post method;
};
John Papa's AngularJS style guide is well put together and covers scenarios in multiple formats. Below is a link to the data-service factory section:
https://github.com/johnpapa/angular-styleguide#separate-data-calls