How to display factory method value in view using angularJS - javascript

Hi,am getting Json data as per my need,when injecting factory to
controller that data I am unable to show in view in angularJs i.e
correct answer div in UI,I will be thankful if anyone can help to me
Controller code:
public JsonResult displayCorrectAnswer()
{
Db.Configuration.ProxyCreationEnabled = false;
var rs = from q in Db.questions
join a in Db.answers on q.Qid equals a.questionID
where a.isAnswer == "1"
select new { a.answer1 };
return Json(rs, JsonRequestBehavior.AllowGet);
}
>Json Data:
[
{"answer1":"4"},
{"answer1":"Modi"}
]
>Script Code:
var myApp = angular.module("QuestionDisplayModule", [])
.controller("QuestionDisplayController", function ($scope, $http, $log, answerService) {
$http.get("displayQuestion").then(function(response)
{
$log.info(response);
$scope.questionsData = response.data;
})
$scope.answerCheck = answerService.choose();
})
myApp.factory("answerService", function ($http) {
var CorrectAnswers = {};
CorrectAnswers.choose = function () {
return $http.get("displayCorrectAnswer").success(function (response) {
response.data;
})
}
return CorrectAnswers;
});
>View Code:
<body ng-app="QuestionDisplayModule">
<form>
<div ng-controller="QuestionDisplayController">
<div ng-repeat="q in questionsData" style="border:groove 1px green">
<h4 style="color: darkmagenta">{{q.QText}}</h4>
<p ng-repeat="a in q.answer1" style="color: cadetblue"><input type="radio" name="answers+{{$parent.$index}}" ng-model="q.selectedAns" value="{{a.option1}}" />{{a.option1}}</p>
<div ng-show="q.selectedAns">your answer is : {{q.selectedAns}}</div>
<div > correct Answer is : {{answerCheck.answer1}}</div>
</div>
</div>
</form>
</body>

var myApp = angular.module("QuestionDisplayModule", [])
.controller("QuestionDisplayController", function ($scope, $http, $log, answerService) {
$http.get("displayQuestion").then(function(response)
{
$log.info(response);
$scope.questionsData = response.data;
})
$scope.answerCheck = answerService.choose().then(function(response) {
$scope.answerCheck = response;
});
})
myApp.factory("answerService", function ($http) {
var CorrectAnswers = {};
CorrectAnswers.choose = function () {
return $http.get("displayCorrectAnswer")
});
>

Related

Pass value from provider to controller in angularJs

I'm trying get data from db to UI. Url given via provider is getting the data.
Controller in controller DetailsProvider.getDashboardDetails() is getting null.
var appmod = angular.module('project.DetailDashboardController', []);
appmod.controller("DetailDashboardController", ['$rootScope', '$scope', '$state', 'DetailsProvider',function($rootScope, $scope, $state,DetailsProvider) {
console.log("DetailDashboardController --- ");
$scope.DetList= DetailsProvider.getDashboardDetails()
}]);
})(window, window.angular);
provider which will call the list
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
Thanks in advance for any kind of reply!
You should return promise from your service method and do thenable in your controller.
Root Cause : your are returning the newData which will initalized later after completing the ajax call.Before completing it,you are returning the same variable which will be always null.
In provider,
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
and in controller,
$scope.list = function() {
DetailsService.getDashboardDetails(function(data){
varr holdIt = data.data.DList;
});
};

AngularJS factory for sharing data between controllers

I have an AngularJS application (1.4.10) and I need to share some data between two controllers.
So I made my factory:
.factory('CardsForService', function($http, URL){
var service = {
"block_id": '',
"service_id": ''
};
service.save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
service.get_data = function(){
return service;
};
return service;
})
I insert the data in the first controller:
$scope.open = function(id, type){
console.log(id +" "+type);
CardsForService.save_data(id, type);
...
And I try to get the data in another controller, like this:
$scope.$on('$routeChangeSuccess', function() {
if (algo_to_used == "service"){
var data = CardsForService.get_data();
console.log(data);
} else {
}
});
The console.log output this:
Object {block_id: "", service_id: ""}
If I try the same get_data() function in the same controller where I call the save_data() function I have the correct results.
What am I missing?
Change Factory Like this
app.factory('CardsForService', function(){
var service = {
"block_id": '',
"service_id": ''
};
var save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
var get_data = function(){
return service;
};
return{
saveData:save_data,
getData:get_data
}});
And in controllers
app.controller('FirstCtrl',function(CardsForService){
CardsForService.setData(id, type);
});
app.controller('SecondCtrl', function($scope, CardsForService){
$scope.data = CardsForService.getData();
});
This sounds like it could be a timing issue. Data from a service like this isn't reactive. Here's a snippet that should help visualize it.
var app = angular.module("demo", []);
app.factory("MySvc", function() {
var data = {};
data.setData = function(key, value) {
this[key] = value;
}
data.getData = function(key, def) {
return key in this ? this[key] : def;
};
return data;
});
app.controller("test1", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(100).then(function() {
MySvc.setData("foo", "bar");
$scope.data = MySvc.getData("foo");
});
}
]);
app.controller("test2", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(500).then(function() {
$scope.data = MySvc.getData("foo", "baz");
});
}
]);
app.controller("test3", ["$scope", "MySvc",
function($scope, MySvc) {
$scope.data = MySvc.getData("foo", "asdf");
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js "></script>
<div ng-app="demo">
<pre ng-controller="test1">Test 1: {{ data }}</pre>
<pre ng-controller="test2">Test 2: {{ data }}</pre>
<pre ng-controller="test3">Test 3: {{ data }}</pre>
</div>
Ok I solved the problem. Basically before I was using this code for the redirect to the new page:
$window.location.assign('/cards/service');
And now I switched to this code:
$location.path('/cards/service');
And it's working.
The only thing is that when it wasn't working when I redirect the page the console in the chrome inspector refresh for every reloading, now the console do not refresh. Can someone tell me the difference between those two functions?

Angular on one of the ng models not accessible

I am working with angular and I am having this issue for a few days. When I tried to submit the form the value of my second drop down is null(selectedDocument dropdown). I posted my code a few days back but nobody could help me. That is why I am reposing the code again.
<div ng-controller="myController">
<form name="myForm" >
<div>
<select ng-model="selectedCompany">
<option value="">-- Select Company --</option>
<option data-ng-repeat="currentSetting in currentSettings" value={{currentSetting.SCACCode}}>{{currentSetting.SCACCode}}</option>
</select>
</div>
<div><input id="Text1" type="text" ng-model="enteredCustomer"/></div>
<div>
<select ng-model="selectedDocument" ng-click="getTypes()">
<option value="">-- Select Doc type --</option>
<option data-ng-repeat="docSetting in docSettings" value="{{docSetting.Doc_Type}}">{{docSetting.Doc_Type}}</option>
</select>
</div>
<input id ="btnAdd" type="button" value="Add new record" ng-click="setNewRecord()"/>
</form>
And this is my javascript
<script>
var myApp = angular.module("myApp", []);
myApp.service('companiesService', ['$http', '$q', function ($http, $q) {
var currentSettings = null;
this.getList = function () {
var def = $q.defer()
if (currentSettings) {
def.resolve(currentSettings);
} else {
$http.post('GetCompanies')
.then(function (response) {
var response = $.parseJSON(response.data)
currentSettings = response;
def.resolve(currentSettings);
});
}
return def.promise;
}
}]);
myApp.service('allCurrentSettingsService', ['$http', '$q', function ($http, $q) {
var allSettings = null;
this.getList = function () {
var def = $q.defer()
if (allSettings) {
def.resolve(allSettings);
} else {
$http.post('GetAllCurrentSettings')
.then(function (response) {
var response = $.parseJSON(response.data)
allSettings = response;
def.resolve(allSettings);
});
}
return def.promise;
}
}]);
myApp.service("deleteService", function ($http) {
this.removeRow = function (recId, compName, custName, docName) {
$http.post('DeleteRecord', { settingID: recId,companyName: compName,customerName: custName, documentName: docName } )
.success(function (data, status, headers, config) {
window.location.reload();
})
.error(function (data, status, header, config) {
});
}
});
myApp.service("setNewRecordService", function ($http) {
this.setNewRecord = function (compName, custName, docName) {
$http.post('SetCurrentRecord', { companyName: compName, customerName: custName, documentType: docName })
.success(function (data, status, headers, config) {
window.location.reload();
})
.error(function (data, status, header, config) {
});
}
});
myApp.service('getDocTypesService', ['$http', '$q', function ($http, $q) {
var docSettings = null;
this.getDocTypes = function (compName, custName) {
var def = $q.defer()
if (docSettings) {
def.resolve(docSettings);
} else {
$http.post('GetDocTypes', { companyName: compName, customerName: custName })
.then(function (response) {
var response = $.parseJSON(response.data)
docSettings = response;
def.resolve(docSettings);
});
}
return def.promise;
}
}]);
myApp.controller('myController', ['$scope', 'companiesService', 'allCurrentSettingsService','deleteService', 'setNewRecordService', 'getDocTypesService',
function ($scope, companiesService, allCurrentSettingsService, deleteService, setNewRecordService, getDocTypesService) {
$scope.currentSettings = '';
companiesService.getList().then(function (value) {
$scope.currentSettings = value;
}),
$scope.allSettings = '';
allCurrentSettingsService.getList().then(function (value) {
$scope.allSettings = value;
}),
$scope.deleteRecordFromDB = function (recId, compName, custName, docName) {
deleteService.removeRow(recId, compName, custName, docName)
},
$scope.companyName = '';
$scope.setNewRecord = function () {
setNewRecordService.setNewRecord($scope.selectedCompany, $scope.enteredCustomer, $scope.selectedDocument)
},
$scope.getTypes = function () {
getDocTypesService.getDocTypes($scope.selectedCompany, $scope.enteredCustomer).then(function (value) {
$scope.docSettings = value
});
};
}
]);
Your might have something something to do with the way angular(and Javascript for that matter) handles scopes.
The short of it is that the problem is that a child scope is breaking the connection to the parent scope(your controller variable). A simple fix is to bind your form variables to an object and refer to them with the dot notation in the view.
You can read up on this in numerous SO answers, for example here:
Why don't the AngularJS docs use a dot in the model directive?
Edit
I made a minimal working plunkr that should point you in the right direction, and here is the edited code.
myApp.controller('myController', ['$scope', 'companiesService', 'allCurrentSettingsService','deleteService', 'setNewRecordService', 'getDocTypesService',
function ($scope, companiesService, allCurrentSettingsService, deleteService, setNewRecordService, getDocTypesService) {
$scope.selections = {company: null, document: null};
$scope.currentSettings = '';
companiesService.getList().then(function (value) {
$scope.currentSettings = value;
}),
$scope.allSettings = '';
allCurrentSettingsService.getList().then(function (value) {
$scope.allSettings = value;
}),
$scope.deleteRecordFromDB = function (recId, compName, custName, docName) {
deleteService.removeRow(recId, compName, custName, docName)
},
$scope.companyName = '';
$scope.setNewRecord = function () {
setNewRecordService.setNewRecord($scope.selected.company, $scope.enteredCustomer, $scope.selected.document)
},
$scope.getTypes = function () {
getDocTypesService.getDocTypes($scope.selected.company, $scope.enteredCustomer).then(function (value) {
$scope.docSettings = value
});
};
}
]);
and html:
<div ng-controller="myController">
<form name="myForm" >
<div>
<select ng-model="selected.company">
<option value="">-- Select Company --</option>
<option data-ng-repeat="currentSetting in currentSettings" value={{currentSetting.SCACCode}}>{{currentSetting.SCACCode}}</option>
</select>
</div>
<div><input id="Text1" type="text" ng-model="enteredCustomer"/></div>
<div>
<select ng-model="selected.document" ng-click="getTypes()">
<option value="">-- Select Doc type --</option>
<option data-ng-repeat="docSetting in docSettings" value="{{docSetting.Doc_Type}}">{{docSetting.Doc_Type}}</option>
</select>
</div>
<input id ="btnAdd" type="button" value="Add new record" ng-click="setNewRecord()"/>
Is the dropdown get data or not
if not
i think in getTypes function ,can you try this
$scope.getTypes = function () {
getDocTypesService.getDocTypes($scope.selectedCompany, $scope.enteredCustomer).then(function (value) {
$scope.docSettings = value.data;
});
}
In your controller you have, for example, this:
companiesService.getList().then(function (value) {
$scope.currentSettings = value;
}),
$scope.allSettings = '';
What's the comma for?
End your call with a ; and with all the others too.
Your first select has the data from that first service call. Then it errors out because of all the comma'd functionality after it. Terminate them correctly, and then when it gets down to settings $scope.docSettings it should be correct.
myApp.controller('myController', ['$scope', 'companiesService', 'allCurrentSettingsService','deleteService', 'setNewRecordService', 'getDocTypesService',
function ($scope, companiesService, allCurrentSettingsService, deleteService, setNewRecordService, getDocTypesService) {
$scope.currentSettings = '';
companiesService.getList().then(function (value) {
$scope.currentSettings = value;
});
$scope.allSettings = '';
allCurrentSettingsService.getList().then(function (value) {
$scope.allSettings = value;
});
$scope.deleteRecordFromDB = function (recId, compName, custName, docName) {
deleteService.removeRow(recId, compName, custName, docName);
};
$scope.companyName = '';
$scope.setNewRecord = function () {
setNewRecordService.setNewRecord($scope.selectedCompany, $scope.enteredCustomer, $scope.selectedDocument)
};
getDocTypesService.getDocTypes($scope.selectedCompany, $scope.enteredCustomer).then(function (value) {
$scope.docSettings = value
});
}
]);
Something like that, my ES5 is a little rusty, but see if that works. Edited: removed the unnecessry docTypes.

How I insert a same data in multiple controllers ($scope) with one call in AngularJS?

I am using a factory to be call in two controllers that are in same page, however I don't want that this call AJAX two times. I'm try use $q.defer(), but it doesn't work!
The code:
(function () {
'use strict';
var app = angular.module('globalApp', []).config([
'$interpolateProvider', '$httpProvider',
function ($interpolateProvider, $httpProvider) {
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
}
]);
// Index Store List
app.controller('IndexController', ['$scope', '$storeList',
function ($scope, $storeList) {
$scope.stores = [];
$storeList.getStoreList().then(function (stores) {
$scope.stores = stores;
});
}]);
// Footer Store List
app.controller('StoreListController', [
'$scope', '$storeList',
function ($scope, $storeList) {
$scope.stores = [];
$storeList.getStoreList().then(function (stores) {
$scope.stores = stores;
});
}
]);
// Factory call list os stores
app.factory('$storeList', function ($http, $q) {
var stores = [];
return {
getStoreList: function () {
//is a request needed?
if (stores.length > 0) {
var deferred = $q.defer();
deferred.resolve(stores);
return deferred.promise;
}
var uri = rootUrl + 'getStoreList';
var responsePromise = $http.get(uri);
return responsePromise.then(function (result) {
var data = result.data;
//modify collection of stores...
if (data.status) {
var stores = data.stores;
return stores;
}
});
}
};
});
}());
<body ng-app="globalApp">
<section>
<div ng-controller="IndexController">
<nav>
<a ng-repeat="store in stores" href="<%store.link%>"><%store.name%></a>
</nav>
</div>
</section>
<footer>
<div>
<ul ng-controller="StoreListController">
<li ng-repeat="store in stores">
<h3><%store.name%></h3>
<p>
<%store.street%>, <%store.number%>
<%store.neighborhood%>, <%store.cityName%>
<a><%store.phone%></a>
<a><%store.email%></a>
</p>
</li>
</ul>
</div>
</footer>
</body>
If both controllers load at the same time and call the function, stores will not contain any data so it's length will evaluate to 0.
If you need to do this onLoad of the page why don't you call the function from a service and store the results. You can utilize an observer pattern in the controls to listen for changes to the set and persist those changes to both controllers to set the value of $scope.stores once the promise resolves.
My solution:
(function () {
'use strict';
// My configs (optional)
var app = angular.module('globalApp', []).config([
'$interpolateProvider', '$httpProvider',
function ($interpolateProvider, $httpProvider) {
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
}
]);
// Index Store List
app.controller('IndexController', [
'$scope', '$storeList', 'StoreService',
function ($scope, $storeList, StoreService) {
$scope.stores = [];
$storeList.getStoreList().then(function (stores) {
$scope.stores = stores;
StoreService.setStores(stores);
});
}]);
// Footer Store List
app.controller('StoreListController', [
'$scope', 'StoreService',
function ($scope, StoreService) {
$scope.stores = [];
$scope.$watch(function () {
return StoreService.getStores();
}, function (stores) {
$scope.stores = stores;
}, true);
}
]);
// StoreService to share vars between the controllers
app.service('StoreService', function () {
var stores = [];
return {
setStores: function (_stores) {
stores = _stores;
},
getStores: function () {
return stores;
}
};
});
// Factory make ajax call to get list of stores
app.factory('$storeList', function ($http) {
return {
getStoreList: function () {
var uri = rootUrl + 'getStoreList';
var responsePromise = $http.get(uri);
return responsePromise.then(function (result) {
var data = result.data;
if (data.status) {
return data.stores;
}
return [];
});
}
};
});
}());
<body ng-app="globalApp">
<section>
<div ng-controller="IndexController">
<nav>
<a ng-repeat="store in stores" href="<%store.link%>"><%store.name%></a>
</nav>
</div>
</section>
<footer>
<div>
<ul ng-controller="StoreListController">
<li ng-repeat="store in stores">
<h3><%store.name%></h3>
<p>
<%store.street%>, <%store.number%>
<%store.neighborhood%>, <%store.cityName%>
<a><%store.phone%></a>
<a><%store.email%></a>
</p>
</li>
</ul>
</div>
</footer>
</body>
You don't need to have defer here. Remove this chunk:
//is a request needed?
if (stores.length > 0) {
var deferred = $q.defer();
deferred.resolve(stores);
return deferred.promise;
}
And your IndexController and StoreListController are both loading the storelist and hence 2 AJAX calls. Remove the chunk from either of the 2 controllers
$scope.stores = [];
$storeList.getStoreList().then(function (stores) {
$scope.stores = stores;
});
EDIT
I Did not realize earlier, but since you are using the storeList outside the scope of your StoreController, You should remove the .getStoreList() call from StoreController only

ngClick not firing in nested ngRepeat filled with data from $http.post()

I have an AngularJS app to search for journeys. In the part of the problem I am trying to show all available countries per region. The idea is that when you click a country, a function has to be executed. But it never fires...
Any help?
View
<div id="headersearch" ng-controller="ProductSearchController">
<div id="headersearchContainer">
<input id="tripchoise" class="field" type="text" placeholder="Hoe ver wil je gaan?" ng-model="country" ng-change="switchView('countries')" ng-blur="switchView('')" ng-focus="switchView('countries')" />
<div id="triptypechoise">
<div class="triptype" ng-class="{active: filter=='single'}" title="Singlereizen" ng-click="switchFilter('single')"><img src="/Resources/Images/Layout/singlereis.png" alt="Singlereizen" /></div>
<div class="triptype" ng-class="{active: filter=='custom'}" title="Maatwerkreizen" ng-click="switchFilter('custom')"><img src="/Resources/Images/Layout/maatwerk.png" alt="Maatwerkreizen" /></div>
<div class="triptype" ng-class="{active: filter=='group'}" title="Groepsreizen" ng-click="switchFilter('group')"><img src="/Resources/Images/Layout/groepsreis.png" alt="Groepsreizen" /></div>
</div>
<div id="tripdeparturedatechoise" class="field arrow">
{{date}}
</div>
</div>
<div id="headersearchButton">
<span>ZOEK</span>
</div>
<div class="clear"></div>
<input type="text" class="datepicker datehide" id="searchdepartureDate" ng-model="date" datepicker/>
<div id="searchList" ng-class="{hide:view==''}">
<div class="loadingproducts" data-ng-show="loading">Loading products...</div>
<article class="searchentry" ng-show="view=='countries'">
<div class="" ng-repeat="region in regions">
<p>{{region.Name}}</p>
<ul>
<li ng-repeat="country in region.Countries">
<a ng-click="test()">{{country.Name}}</a>
</li>
</ul>
</div>
</article>
</div>
</div>
CONTROLLER
SearchApp.controller("ProductSearchController", function ($scope, $http) {
$scope.date = "Vertrek";
$scope.filter = "single";
$scope.view = "";
$scope.country = "";
$scope.switchFilter = function (filter) {
if ($scope.filter != filter) {
$scope.filter = filter;
$scope.search();
}
}
$scope.switchView = function (view) {
if ($scope.view != view)
$scope.view = view;
if ($scope.view != "" && $scope.view != "countries")
$scope.search();
}
$http.post("/AVProductList/GetCountriesByRegionAsync")
.success(function (response) {
$scope.regions = response.regions;
});
$scope.search = function () {
$scope.loading = true;
$http.post("/AVProductList/SearchProductsHeader?view="+ $scope.view +"&filter=" + $scope.filter, { SearchParameters: {Country: $scope.country}})
.success(function (data) {
if ($scope.filter == "custom")
$scope.trips = data.results;
else {
if ($scope.view == "trips")
$scope.trips = data.grouped.RoundtripgroupCode.doclist.docs;
else if ($scope.view == "departures")
$scope.trips = data.response.docs;
}
});
};
$scope.changeDate = function () {
if (isValidDate($scope.date)) {
$scope.view = "departures";
$scope.search();
}
else {
$scope.date = "Vertrek";
$scope.view = "trips";
}
}
$scope.selectCountry = function (name, code) {
$scope.countrycode = code;
$scope.country = name;
$scope.view = isValidDate($scope.date) ? "departures" : "trips";
$scope.search();
}
$scope.test = function () {
alert("Hoi");
}
});
Json result example of
$http.post("/AVProductList/GetCountriesByRegionAsync")
.success(function (response) {
$scope.regions = response.regions;
});
{
regions:[
{
Name:"Asia",
Countries:
[
{
Name: "China",
Code: "CH"
}
,...
]
}
,...
]
}
I made a stupid mistake:
The ngBlur on "tripchoise" was fired before the ngClick.

Categories