I use the Tab Template, with list of chats and chats detail. I've put the data into a json file, and add it like this in my code : $http.get("http://abcd/Chats.json").
The data are showing on the List of Chats, but it doesn't work on the Detail Page.
I've tested a lot of solution, but I'm still getting an error...
Here is my code:
SERVICE
angular.module('starter.services', [])
.factory('Chats', function($http) {
// Might use a resource here that returns a JSON array
return {
getChats: function() {
return $http.get("http://abcd/Chats.json").success(function(response){
chats=response;
return chats;
});
},
get: function(chatId) {
for (var i = 0; i < chats.length; i++) {
if (chats[i].id === parseInt(chatId)) {
return chats[i];
}
}
return null;
}
};
});
CONTROLLER
.controller('ChatsCtrl', function($scope, Chats) {
Chats.getChats().success(function(response){
$scope.chats =response;
});
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Chats) {
$scope.chat = Chats.get($stateParams.chatId);
} )
My error is: cannot read property of chat undefined..
Any help please?
Try to define chats as a var inside your factory.
.factory('Chats', function($http) {
var chats;
...
Related
This is my controller which is calling the login service
mod.controller("loginCtrl",function($scope,loginService,$http)
{
$scope.Userlogin = function()
{
var User = {
userid :$scope.uname,
pass:$scope.pass
};
var res = UserloginService(User);
console.log(res);
alert("login_succ");
}
});
And this is the login service code which takes the User variable and checks for username & password
mod.service("loginService",function($http,$q) {
UserloginService = function(User) {
var deffered = $q.defer();
$http({
method:'POST',
url:'http://localhost:8080/WebApplication4_1/login.htm',
data:User
}).then(function(data) {
deffered.resolve(data);
}).error(function(status) {
deffered.reject({
status:status
});
});
return deffered.promise;
// var response = $http({
//
// method:"post",
// url:"http://localhost:8080/WebApplication4_1/login.htm",
// data:JSON.stringify(User),
// dataType:"json"
// });
// return "Name";
}
});
I have created a rest api using springs which upon passing json return back the username and password in json like this
Console shows me this error for angular
You need to enable CORS for your application for guidance see this link
https://htet101.wordpress.com/2014/01/22/cors-with-angularjs-and-spring-rest/
I prefer to use Factory to do what you're trying to do, which would be something like this:
MyApp.factory('MyService', ["$http", function($http) {
var urlBase = "http://localhost:3000";
return {
getRecent: function(numberOfItems) {
return $http.get(urlBase+"/things/recent?limit="+numberOfItems);
},
getSomethingElse: function(url) {
return $http.get(urlBase+"/other/things")
},
search: function (searchTerms) {
return $http.get(urlBase+"/search?q="+searchTerms);
}
}
}]);
And then in your controller you can import MyService and then use it in this way:
MyService.getRecent(10).then(function(res) {
$scope.things = res.data;
});
This is a great way to handle it, because you're putting the .then in your controller and you are able to control the state of the UI during a loading state if you'd like, like this:
// initialize the loading var, set to false
$scope.loading = false;
// create a reuseable update function, and inside use a promise for the ajax call,
// which is running inside the `Factory`
$scope.updateList = function() {
$scope.loading = true;
MyService.getRecent(10).then(function(res) {
$scope.loading = false;
$scope.things = res.data;
});
};
$scope.updateList();
The error in the console shows two issues with your code:
CORS is not enabled in your api. To fix this you need to enable CORS using Access-Control-Allow-Origin header to your rest api.
Unhandled rejection error, as the way you are handling errors with '.error()' method is deprecated.
'Promise.error()' method is deprecated according to this and this commit in Angular js github repo.
Hence you need to change the way you are handling errors as shown below :
$http().then(successCallback, errorCallback);
function successCallback (res) {
return res;
}
function errorCallback (err) {
return err;
}
One more thing in your code which can be avoided is you have defined a new promise and resolving it using $q methods, which is not required. $http itself returns a promise by default, which you need not define again inside it to use it as a Promise. You can directly use $http.then().
I try to use ng-tags-input with a returned Json list by an api controller .net Mvc 6. My list is created in json but when try to display this list with the autocompletion , nothing works. My autocomplete list isn't displayed and I don't have error in chrome console.
So this is an object of my list :
[{
"ShopID":1,
"CompanyID":1,
"RegionID":1,
"Name":"Les Pieux",
"Town":"Les Pieux",
"Address":null,
"ZipCode":null,
"CreateDate":"2006-01-01T00:00:00",
"ModificationDate":"2006-09-29T00:00:00",
"LastModificationUserID":1,
"PhoneNumber":null,
"Fax":null,
"Email":null,
"CEmployeeShop":null
}]
This is my method in my controller:
$scope.tokenShops = [];
$scope.loadJsonShops = function(query)
{
//$scope.shops contains my list of shops in json format.
return $scope.shops;
}
And the tag in Html:
<div ng-controller="EmployeesCtrl">
<tags-input ng-model="tokenShops"
display-property="Name"
Placeholder="Ajouter un magasin"
add-from-autocomplete-only="true">
<auto-complete resource="loadJsonShops($query)"></auto-complete>
</tags-input>
</div>
This is my code that populates $scope.shops
Api Controller:
public IEnumerable<Shop> Get()
{
using (LSContext db = new LSContext())
{
var listShop = db.Shops.ToList();
return listShop;
}
}
angular shopCtrl:
function ShopsCtrl($scope, $http, $rootScope) {
function getShopsList() {
var reqGetShops = $http({ url: 'api/Shops' });
reqGetShops.success(function (data) {
$scope.shops = data;
$rootScope.$broadcast("getListShops", { list: data });
});
}
//with api controller the list is returned in json format. I tried an another method to fill my list with an convertion that I do and it doesn't work.
angularjs EmployeeCtrl :
$scope.$on("getListShops", function (event, args) {
$scope.shops = args.list;
$scope.selectShop = args.list[0];
})
But I don't think that my problem from my json list.
I hope someone can help me . Have a nice day.
I resolve my problem with a directive:
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
});
and in Html:
<tags></tags>
g0loob : thanks for your help, but now you can put an array of objects and use the attribute display-property to choose the text property to display.
example:http://mbenford.github.io/ngTagsInput/demos and look the tags input with custom object.
auto-complete requires array of objects with at least one property named "text" (just like tags-input), if you are not using your template for auto-complete or tags-input. And you also need to filter your result for auto-complete in order to work properly. Also see this link.
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
I am new to angular and I am trying to load a CSV list inside a factory and then convert it to json. I am using Papaparse (CSV to json library) inside the factory. When I console log the factory I get the array of objects which is exactly what I want but when I pass it inside my controller I get a single object which holds all the data.
This is my factory
(function() {
var app = angular.module('test');
app.factory('testFactory', ['$http', function($http) {
var url = 'my-list.csv';
var getContact = function() {
return $http.get(url).success(function(data) {
Papa.parse(data, {
header: true,
complete: function(results) {
console.log(results.data);
return results.data;
}
});
});
};
return {
getContact: getContact
};
}]);
}());
And this is my controller
(function() {
var app = angular.module('test');
app.controller('testCtrl', ['$scope', 'testFactory', function($scope, testFactory) {
testFactory.getContact().then(function(data) {
$scope.contacts = data;
console.log(data);
});
}]);
}());
I want be able to do something like this inside my view
{{ contact.firstname }}
The issue is the order of resolution. Inspecting the console statements shows that you're assigning $scope.contacts to the resolution of the $http.get promise, and not the actual parsing.
Instead of returning the $http.get promise, return a deferred promise and resolve at the end of parsing:
var parsePromise = $q.defer();
$http.get(url).success(function(data) {
Papa.parse(data, {
header: true,
complete: function(results) {
console.log(results.data);
parsePromise.resolve(results.data);
}
});
});
return parsePromise.promise;
See working demo here.
Update: As per the comments, you could use .then to chain promises instead of creating a new deferred. The plunkr has both, you can use the changelog to toggle methods.
This is an interesting question. I'm using a simple JSON Get request to get all the competetions according to date, and show result as a list.
the JSON response is kind of :
[
{
"id":33
"competition":565
},
{
"id":66
"competition":345
}
]
Then I should make another json request to get the name of each json item :
myserver.com/{id}
which look like :
{
"name":"Serie A"
}
I want to show a list of all the names of the competetions I have on the first json request according to date.
here is my angular js code for showing the list of a simple JSON request :
<div ng-controller="customersCtrl">
<ul>
<li ng-repeat="m in matches">
{{ m.id }}
</li>
</ul>
</div>
<script>
var app = angular.module('starter', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://Myserver.com/matches?date=2015-05-19")
.success(function (response) {$scope.matches = response;});
</script>
You can iterate through the matches and get the names with a new call:
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://myserver.com/matches?date=2015-05-19")
.success(function (response) {
$scope.matches = response;
for (var i = 0; i < response.length; i++) {
setName($scope.matches, i);
}
});
var setName = function (matches, index) {
$http.get("http://myserver.com/" + matches[index].id)
.success(function (response) {
matches[index].name = response.name;
});
}
});
Below code will first fetch all the competitions and then using their ids it will fetch names all the events parallely. it will give all the competition with details in one go only.
Warning: If you have large numbers of all competition then it will make same number of calls to get competition details all of them.
app.service('competition', function($http) {
this.getAllCompetitions = function() {
var baseUrl = 'http://Myserver.com';
return $http.get(baseUrl + '/matches?date=2015-05-19')
.then(function(allCompetitions) {
/* sample `data`
[
{
"id":33
"competition":565
},
{
"id":66
"competition":345
}
]
*/
var qArr = [];
allCompetitions.forEach(function(competition, index) {
var promise = $http.get(baseUrl + '/' + competition.id)
.then(function(competitionDetail) {
/* sample `competitionDetail`
{
"name":"Serie A"
"competition":565
}
*/
return {
competitionDetail: competitionDetail,
index: index
};
});
aArr.push(promise);
});
return $q.all(qArr).then(function(listOfData) {
listOfData.forEach(function(item) {
allCompetitions[item.index] = angular.extend(allCompetitions[item.index], item.competitionDetail);
});
return allCompetitions;
});
});
}
});
I am trying to display nested JSON in a page. I'm not sure how to drill down into it.
In my app js file I have an parameter called initialData that I want to call a function getProducts() when the view is called...
'use strict';
var quoteApp = angular.module('quoteApp', ['ui.router']);
quoteApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'ng-views/choose.html',
controller: "quoteBuilderController",
resolve: {
initialData: ['quoteApi', function (quoteApi) {
return quoteApi.getProducts();
}]
}
})
});
my quoteApi looks like this in case you want to see it...
(function () {
'use strict';
angular.module('quoteApp').factory('quoteApi', quoteApi);
quoteApi.$inject = ['$http'];
function quoteApi($http) {
var service = {
getProducts: getProducts,
getPrices: getPrices
};
var baseUrl = 'http://www.website.com/api/Pricing';
return service;
function getProducts() {
return httpGet('/GetProductCatalogue');
}
function getPrices() {
return httpGet('/GetPrices');
}
/** Private Methods **/
function httpExecute(requestUrl, method, data){
return $http({
url: baseUrl + requestUrl,
method: method,
data: data,
headers: requestConfig.headers }).then(function(response){
return response.data;
});
}
function httpGet(url){
return httpExecute(url, 'GET');
}
}
})();
So quoteApi.getProducts() returns JSON that looks like this...
{
"Cat1": [
{
"product_id": 1,
"product_name": "Prod1"
},
{
"product_id": 2,
"product_name": "Prod2"
}
],
"Cat2": [
{
...
}
]
}
My controller for the view looks like this...
(function () {
'use strict';
angular.module('quoteApp').controller('quoteController', ['$scope', '$http', '$timeout', quoteController]);
quoteController.$inject = ['initialData', 'quoteApi'];
function quoteController($scope, initialData) {
$scope.cat1Products = initialData;
};
})();
So my question is, how can I get 'initialData' to load products from Cat1 only? Should I try to do this from the html? It seems like it should be straight forward enough but I can seem to get it. Thank you.
You need to transform your response from your http request further so you only return the piece you require, and you may also want to consider using the .then() approach:
$http.get('/someUrl').then(function(response) {
//Do something with response.data.Cat1 here
}, function(errResponse) {
console.error('Error while fetching data');
});
Just take out cat1 from your initialData object
function quoteController($scope, initialData) {
$scope.cat1Products = initialData['Cat1'];
};