So my ui bootstrap model window is working correctly but when I add an object to the controller it stops showing and it doesn't give me any error in consol.
When my controller looks like this:
"use strict";
app.controller('RegisterModalCtrl', ['$scope', '$location', '$uibModalInstance', '$http', 'ngAuthSettings', 'registerService',
function($scope, $location, $uibModalInstance, $http, ngAuthSettings, registerService) {
var $ctrl = this;
$ctrl.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
/*
$ctrl.registerInfo = {
email: $ctrl.registerData.email,
nick: $ctrl.registerData.nick,
password: $ctrl.registerData.password,
password_confirmation: $ctrl.registerData.confirm_password
};
*/
$ctrl.registerSubmit = function(registerInfo) {
console.log('im in registerSubmit controller function');
registerService.registerUser(registerInfo);
$uibModalInstance.dismiss('cancel');
};
$ctrl.showCookiesRules = function() {
$location.url("/cookiesrules");
$uibModalInstance.dismiss('cancel');
};
$ctrl.showRules = function() {
$location.url("/rules");
$uibModalInstance.dismiss('cancel');
};
}]);
Everything works just fine but when i delete /* just before registerInfo object it stops showing. What is wrong with this object? I want it to create this object to pass it in function and then pass it to function in service.
So what you should do is initiate $ctrl.registerInfo:
$ctrl.registerInfo = {};
The data doesn't exist when the controller runs, so you are trying to set the properties of $ctrl.registerInfo without non-existent data. Once your form is filled out, the properties/data will be set.
An alternative option would not be to initialize at all, and simply set your form model to registerData.confirm_password, and when you call registerSubmit, call it with registerSubmit(registerData). That will send the data to that method without having to initialize in the controller:
<input type="text" placeholder="powtórz hasło"
ng-model="registerData.confirm_password" />
<!-- abbreviated (other form fields here -->
<input type="submit" ng-click="registerSubmit(registerData)" />
If you need the data afterwards, in registerSubmit, add a line:
$ctrl.registerInfo = registerInfo;
However, I am not sure you'd want to hang onto the password there.
AngularJS Form Docs: https://docs.angularjs.org/guide/forms
Related
I am trying to consume my ASP.NET Web API using AngularJs. The problem is that i want to pass optional parameters to the url based on the user input(2 Html Text Boxes) but i don't know how.
This is my ASP.NET Web API Controller
[Route("api/JobShow/{keyword}/{location}")]
public class JobShowController : ApiController
{
[HttpGet]
public PageResult<sp_JobSearch_Result> Get(ODataQueryOptions<sp_JobSearch_Result> options, string keyword = null, string location = null)
{
ODataQuerySettings settings = new ODataQuerySettings()
{
PageSize = 20
};
JobWindow obj = new JobWindow();
IQueryable results = options.ApplyTo(obj.showJobs(keyword, location).AsQueryable(), settings);
return new PageResult<sp_JobSearch_Result>(
results as IEnumerable<sp_JobSearch_Result>,
Request.GetNextPageLink(),
Request.GetInlineCount());
}
}
And this is my AngularJS controller
angular.module('JobSearch.SiteController', []).controller('JobSearchCtrl', ['$scope', '$http', function ($scope, $http) {
$http.get('/api/JobShow').success(function (data) {
$scope.model = data;
});
}]);
Example of the url then would be .../api/JobShow/Java/Toronto. Thank you all.
You can try ngResource !
You first need to include ng-resource
<script src="angular.js">
<script src="angular-resource.js">
You can get it via Bower or CDN, or whichever way you got AngularJS.
HTML:
<body ng-app="MyApp">
<div ng-controller="MyCtrl">
<label>Keyword: <input type="text" ng-model="keyword" /></label>
<label>Location: <input type="text" ng-model="location" /></label>
<button ng-click="getJobShowPage(keyword, location)">Search</button>
</div>
</body>
Controller:
angular
.module('MyApp', ['ngResource']) // Include the ngResource module here
.controller('MyCtrl', ['$scope', '$resource', function($scope, $resource){
// Create the $resource
var JobShowPage = $resource('/api/JobShow/:keyword/:location', {keyword: "#keyword", location: "#location"})
// Make a scope function to use the resource properly
$scope.getJobShowPage = function(keyword, location) {
var parameters = {};
if (keyword) {
parameters["keyword"] = keyword;
if (location) {
parameters["location"] = location;
}
}
return JobShowPage.get(parameters);
};
}]);
Input/Outputs:
When the user enters nothing and clicks 'Search', the HTTP request would be /api/JobShow
If only the keyword is entered, the HTTP request would be /api/JobShow/{{keyword}}
If both the keyword and location is entered, the HTTP request would be /api/JobShow/{{keyword}}/{{location}}
If only the location is entered (no keyword), the HTTP request would be the vanilla one /api/JobShow
You can consume the return value of the $resource query like a promise:
JobShowPage.get(parameters).$promise.then(function(response){
// Do Stuff
$scope.model = response.data;
});
by callbacks:
JobShowPage.get(parameters, function(err, response){
// Do Stuff
$scope.model = response.data;
});
Or auto unwrap it:
// This works, but it's asynchronous
// Useful if consuming directly from the Angular Template
$scope.model = JobShowPage.get(parameters);
Based on your code, I'm going to assume you have 2 textboxes and a search button, and when the search button is pressed, you want to call your GET endpoint. For this scenario, what you'll want to do is bind the textbox inputs to your scope and bind the search button using ng-click to a function in your scope that will call your endpoint. It might look something like this:
controller
angular.module('JobSearch.SiteController', [])
.controller('JobSearchCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.getResults= getResults;
function getResults() {
$http.get('/api/JobShow/' + $scope.keyword + '/' + $scope.location).success(function (data) {
$scope.model = data;
});
}
}]);
html
<div ng-controller="JobSearchCtrl">
<input type="text" ng-model="keyword">
<input type="text" ng-model="location">
<button type="button" ng-click="getResults()">Search</button>
</div>
I have a controller that ive added a function to but cant get the function to be called from ng-click on an anchor. Ive looked at similar posts but cant really see what I could be missing. Its as though the controller function cant be seen?
The module and controller:
var commonModule = angular.module('common', ['ngRoute', 'ng.ckeditor']);
var mainModule = angular.module('main', ['common']);
//mainModule.config(function ($routeProvider, $locationProvider) {
// $locationProvider.html5Mode(true);
//});
commonModule.factory('viewModelHelper', function ($http, $q, $window, $location) {
return MyApp.viewModelHelper($http, $q, $window, $location);
});
commonModule.factory('validator', function () {
return valJs.validator();
});
mainModule.controller("rootViewModel",
function ($scope, $http, $q, $routeParams, $window, $location, viewModelHelper, $rootElement) {
//test
console.log("creating controller");
var self = this;
viewModelHelper.apiGet('api/PageContent/1', null,
function (result) {
$scope.htmlEditor = result.data;
});
$scope.ToggleEditor2 = function () {
//test
console.log("hello");
if ($scope.editorVisible == true) {
$scope.editorVisible = false;
}
else {
$scope.editorVisible = true;
}
}
});
The controller is referenced at the root level of the page:
Which in this case since im using ASP.Net MVC, is in my _layout.cshtml
<body data-ng-app="main" data-ng-controller="rootViewModel">
In a (mvc) view that gets loaded, I have a button with ng-click that calls the ToggleEditor2 function, but its never called. Cant get a breakpoint to hit in the chrome dev console and I dont see anything written to the log either.
<input type="button" ng-click="ToggleEditor2()" value="test me" />
Update:
If I wrap that anchor with a div and specify the "rootviewModel" controller there, the log message gets written. Hmmm - something tells me its related to scope?
<div data-ng-controller="rootViewModel">
<input type="button" ng-click="ToggleEditor2()" value="test me" />
</div>
Problem
A common problem with $scope is that when using any sort of nested controllers or modules, your $scope's can step on each other and cause issues like you have experienced.
Solution
Using Angular's "Controller As" syntax is the recommended solution for this problem. It allows you to create multiple instances of the same controller, while defining and maintaining a unique scope for each instance.
This Article is a great resource I used to understand and implement this new syntax.
I have a controller HomeworkPageController where I get all the topics from MongoDB using method getAllMainTopics from TopicService. $scope.topics is then used to show all topics. I have a button that open a modal where a new topic is add in MongoDB. The modal is using another controller AddTopicController. How can I update $scope.topics from HomeworkPageController in AddTopicController ? I want to do this because after I close the modal, the list of all topics should be refreshed, it must contain the topic that has been added. I tried to use HomeworkPageController in AddTopicController and then call the method getAllMainTopics but the $scope.topics from html is not updated. Thanks.
Here is HomeworkPageController:
app.controller('HomeworkPageController', ['$scope','TopicService',
function ($scope, TopicService) {
$scope.topics = [];
$scope.getAllMainTopics = function () {
TopicService.getAllMainTopics('homework')
.success(function(data) {
$scope.topics = data;
}
$scope.addTopic = function () {
ModalService.openModal({
template: "templates/addTopic.html",
controller: 'AddTopicController'
});
}
]);
Here is AddTopicController:
app.controller('AddTopicController', ['$scope','$controller', '$timeout','TopicService', '$modalInstance',
function ($scope, $controller, $timeout,TopicService, $modalInstance) {
var homeworkPageController = $scope.$new();
$controller('HomeworkPageController',{$scope : homeworkPageController });
$scope.save = function() {
TopicService.saveTopic(data)
.success(function(result){
homeworkPageController.getAllMainTopics();
$modalInstance.close();
})
}
}]);
Here is the view where I use $scope.topics:
<div class="homework-content-topic-list" ng-repeat="topic in topics">
<label> {{ topic.subject }} </label>
</div
You should probably keep your list of topics in a service and then inject that service into both controllers. This way you would be able to access and update the topics in both of your controllers. It could look something like
app.controller('HomeworkPageController', ['$scope','TopicService',
function ($scope, TopicService) {
$scope.topics = TopicService.topics;
// Do stuff here
]);
Then you just need to modify your TopicService to have it's methods work on the stored object.
you can solve this by two methods
1)look at the example given in ui-bootstrap's website. They have given an example that will suit your requirement - plunker. There are three items in the modal - item1, item2, item3. If you select one of those items and click 'ok', the selected item is sent to the main controller through "resolve" attribute in the $scope.open function.
2)You can write a custom service that acts as a bridge to the two controllers and you can write getter and setter methods in the service.
angular.module('app').service('popupPageService', function() {
var topics;
var setDetails = function(param) {
topics = param;
};
var getDetails = function() {
return topics;
};
return {
setDetails: setDetails,
getDetails: getDetails,
};
});
call the setDetails function in the AddTopicController and once when you come out of the modal, update your $scope.topics in HomeworkPageController by pushing the new value added (getDetails)
I am newbie for angularjs.I have list of persons and each person have edit and delete button. when i click to edit button ng-dialog box was open and show person details and person can change and save information on database,behind save button ajax call trigger and update information on database.
Updating information on database work well but on UI side my view doesn't reflect my database changes.
I had tried to apply "$scope.$apply();" method but i got error message "$digest already in progress".
Please help me,how can refresh my scope after ajax call.
You can use shared service for that and broadcast any event through this service. Broadcasted event can be listened in any controller with $scope.$on.
For example:
angular.module("app", []).factory("sharedService", function($rootScope){
var mySharedService = {};
mySharedService.values = {};
mySharedService.personWasUpdated = function(){
$rootScope.$broadcast('update');
}
return mySharedService;
});
Ctrl for person editing.
app.controller('personEditController', ['$scope', 'sharedService', '$http', function ($scope, sharedService, $http) {
$scope.updatePerson = function(newPerson){
$http.post("../some URL/..", {person: newPerson})
.success(function(data){
sharedService.personWasUpdated(); //event broadcasing
})
};
}
Ctrl for displaying list of persons.
app.controller('personController', ['$scope', 'sharedService', '$http', function ($scope, sharedService, $http) {
var loadPersonsData = function(){
$http.get("../some URL/..").
.success(function(data){
$scope.persons = data;
})
};
loadPersonsData(); //first load
$scope.$on('update', function () {
loadPersonsData(); // load after update of any person
});
}
Try with $scope.$digest(); or use $http instead jQuery ajax or others
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 +
'¶meter2=' + 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;
}
}
});