Close angular bootstrap modal window from a controller - angularjs

I have a contact form inside my modal window. After successful post request i want to close the modal automatically. I am using MEAN.JS
here is my controller
angular.module('core').controller('FormCtrl',['$scope','$http', function($scope,$http) {
$scope.postMail = function (data) {
$http.post('/mail', data).
success(function(data, status, headers, config) {
alert('success');
//close function....??
}).
error(function(data, status, headers, config) {
});
};
}]);//formController ends
How can i close my modal after $http.post success?

I got something for you
Use:- $modalStack
And then call $modalStack.dismissAll();
Simple plunker
I used $timeout in plunkler you can use it anywhere like $http :-)
Doc

As crude as it is...
Set the modal as a variable on the scope then just pass it through a function on the template and call modalVarName.dismiss();

For me using $modalStack gave me injection error even though I injected $modal and $modalStack as dependency. Following worked:
angular.element(document.querySelector('#modal')).modal('hide');

Related

What is the best way to initiate an AngularJS controller function that uses a service that make an HTTP request

I'm new on AngularJS. I would like to know what is the best way to use pure AngularJS to initiate a controller that uses a service that makes an HTTP request to an external source and as a response receives a JSON object.
The controller is being used to fetch information that will be shown as part of the landing page (welcome information).
I have tried:
In the HTML invoke the function with the ng-init, with alias for the controller and without alias.
In the controller make the explicit call to the service, and in the configuration of routes, resolve primitive to call the Service and save it a a variable at the configuration file.
In the controller receive as a parameter the response of the service and in the configuration of routes, use the resolve primitive to call the Service and save it as a variable with the name of the parameter that the controller receives.
In the controller save the response as a $scope variable, but it is always undefined an nothing is bound to the HTML. Is it necessary to create a value or a directive or something for saving an object in the scope? Also tried doing it at the service with $scope as parameter with the same results (undefined $scope variable).
These options effectively trigger the HTTP request and pass through the lines of the controller function. The problem is that the response is not available for the controller. Under debug mode I can only see that is an object but it doesn't behaves as a JSON object so can't access to none of the properties.
I used the .then at the controller, but although now the data is saved in the $scope, it shows [OBJECT OBJECT] and I can't access to the properties of the JSON object that is saved as the response of the http request. Any ideas?
The function of the service that makes the request like the following:
myAppModule.factory('ClimateService', function ($http) {
return {
getLocation: function () {
return $http.get("some_url/json")
then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
//
});
}
}
});
Under debug I can see the 200 response and the JSON of it. Content-Type:application/json; charset=utf-8
After several changes, none of them are triggering and I am getting an injection error. I have included the local angular-routes in the HTML header, fetched with bower.jason to the project at NetBeans. And included as the first dependency or parameter to the ngRoute
angular.module('app',['ngRoute', ...
angular.module('app.routes', ['ngRoute', 'app.core'])
.config(config);
angular.module('app.core', []);
By the way, the Angello project at GitHub injects neither services nor much parameters and the book doesn't cover this topic in depth.
Is it the version of AngularJS?
Uncaught Error: [$injector:modulerr]
http://errors.angularjs.org/1.4.8/$injector/modulerr?p0=app&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.4.8%2F%24injector%2Fmodulerr%3Fp0%3Dapp.config%26p1%3DError%253A%2520%255B%2524injector%253Anomod%255D%2520http%253A%252F%252Ferrors.angularjs.org%252F1.4.8%252F%2524injector%252Fnomod%253Fp0%253Dapp.config%250A%2520%2520%2520%2520at%2520Error%2520(native)%250A%2520%2520%2520%2520at%2520http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A6%253A416%250A%2520%2520%2520%2520at%2520http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A24%253A186%250A%2520%2520%2520%2520at%2520b%2520(http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A23%253A251)%250A%2520%2520%2520%2520at%2520http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A23%253A494%250A%2520%2520%2520%2520at%2520http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A38%253A117%250A%2520%2520%2520%2520at%2520n%2520(http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A333)%250A%2520%2520%2520%2520at%2520g%2520(http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A37%253A488)%250A%2520%2520%2520%2520at%2520http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A38%253A134%250A%2520%2520%2520%2520at%2520n%2520(http%253A%252F%252Flocalhost%253A8383%252Fapp_demo_app%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A333)%0A%20%20%20%20at%20Error%20(native)%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A6%3A416%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A38%3A391%0A%20%20%20%20at%20n%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A333)%0A%20%20%20%20at%20g%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A37%3A488)%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A38%3A134%0A%20%20%20%20at%20n%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A333)%0A%20%20%20%20at%20g%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A37%3A488)%0A%20%20%20%20at%20eb%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A41%3A249)%0A%20%20%20%20at%20c%20(http%3A%2F%2Flocalhost%3A8383%2Fapp_demo_app%2Fbower_components%2Fangular%2Fangular.min.js%3A19%3A463) (23:05:42:235 | error, javascrip
It's a bit tricky because you have to use promises (.then), but here's a super simple 'get' example.
On the Service:
function mainService($http) {
this.getData = function () {
return $http.get('/api/yourUrl') //a basic 'get' api call
.then(function (response) { //it takes time, so include a promise
return response.data;
});
};
}
And the Controller:
function homeController($scope, friendService) {
$scope.getData = function () {
mainService.getData()
.then(function (data) { //you also need a promise on controller
$scope.ourData = data; //finally put what you get on your scope
});
};
}
Note these examples don't show the defining of the controller and the service - let me know if you're confused.
let's suppose you'll use $http service to request data.
angular.module('app.core', [])
.controller('CoreController', CoreController);
CoreController.$inject = ['$scope', '$http'];
function CoreController($scope, $http) {
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
$scope.data = response.data;
}, function errorCallback(response) {
alert('something odd happens.');
});
};
in your html
<div ng-bind-html="data">
</div>
or if you want to fill a form input:
<input type="text" ng-model="data" />
From what I understood, I am suggesting few things to keep in mind . May be its not what you are looking for but it might help.
ng-init is called as the very first thing inside a controller. You can use promise in case you have to keep things in sync.
If you dont want to get into promise, simply do $http call from controller as it by default handles promise using .success & .error function.
You can't expect some $scope variable to be valid under html if it is inside service. Refer docs.
var mainApp = angular.module("mainApp",[]);
mainApp.controller("serviceController",function($scope,$http){
$http.get("/fetchData_url/").success(function(response){
$scope.data = response;
});
});

How to stop $http being called multiple times in an Angular controller

Inside my Controller I have tried to stop $http being called multiple times, but my efforts seem to be in vein.
I only want the report's items to be loaded once.
Have tried checking for items being undefined and having a timesrun variable at the top of the Controller and increasing by 1 at the bottom of it.
if ($scope.items === undefined && $scope.timesrun == 0)
{
var req = {
method: 'GET',
*snipped*
};
$http(req).success(function (data, status, headers, config) {
$scope.items = data;
}).error(function (data, status, headers, config) {
SweetAlert.swal("Error " + status, data, "error");
});
}
I have even had this in a service but the service just gets called multiple times.
I'm clearly missing a trick. I can understand the digest cycle and I do have expressions in the page that need to be checked so I can see why the controller is running multiple times, but I cannot understand how I can get it to exclude the web calls after they've run once.
Being called $http service twice or more may be due to many reasons. Few I am listing below:
Do not mention controller (see : omit ng-controller='HomePanel' in html) name in template.
If you are using ngRoute, and mentioning controller name in template, as well in route config, it may be calling twice. For example. In app.js
app.config([ '$routeProvider', '$sceProvider',
function($routeProvider, $sceProvider) {
$routeProvider.when('/', {
templateUrl : 'Home',
controller : 'HomePanel',
});
}]);
and in HTML:
<script type="text/ng-template" id="Home">
<div ng-controller="HomePanel">
</div>
</script>
Don't let you ajax call to cache. So append some random value in end of your URL.
var req =
{
method: 'GET',
url : someUrl + "&random="+ Math.random();
};
Hope this may help.
Instead of using $http in controller put it in a function in a custom service and call that function when you want to update data from controller or you can call $http in service and assign it to a variable and use that in controller.

how to share data between two controllers in angularjs

Iam trying to share the data returned by $http to another controller.
$scope.getClickData=function(dataId){
var postData={"containerInstanceId" : "3842a251-1708-4df0-b941-db27a03d91ab","fetchMetadata":true,"parameters":{"#{organizationTypeID}":"abf1c91f-fea8-4033-a731-136c339525c7"}};
$http.post('http://latest.tapplent.info/api/app/layouts/v1/container-instance/data',postData).
success(function(data, status, headers, config) {
$scope.data=data;
console.log(data.containerData[0].propertyData.NULL[0].organizationTypeName.value);
}).
error(function(data, status, headers, config) {
console.log("error");
});
}
});
app.controller('webView', ['$scope', function($scope) {
console.log($scope.data);
}]),
How can i get data to webview controller. Please help me friends how can i solve this problem.
Thanks in advance.
By Three ways.
1.) You can use Angular factory/services.
myApp.factory('unicornLauncher', ["apiToken", function(apiToken) {
return new UnicornLauncher(apiToken);
}]);
https://docs.angularjs.org/guide/providers
2.) By use of broadcast and Emit.
You can share data via $broadcast or $Emit and then catch this data in any controller via $on.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
I prefer Angular factory/services over broadcast/emit due to performance.
3.) Or you can use $rootscope. But that is least preferred as rootscope is your global scope. You should not litter your global scope.
The absolutely simplest way to do this would be to write the data to the rootScope.
$rootScope = data;
A better way would be to wrap the $http call in a service with methods to perform the call and retrieve the data and inject that into both controllers.
Other Way That I Usually Do like Angularjs Wire up a Backend 2nd last Example
controller1.js
from controller1 just pass dataId to controller2 and controller2 will contain request code that will bring data and populate in scope.
$scope.onButtonClick = function () {
$location.url('/controller2?dataId='+33);
//$scope.getClickData=function(dataId){}); add this func to controller2.js
}
This Code in controller1.js will
pass small dataId to other controller2.js
also navigate you to other controller2.js
controller2.js
app.controller('controller2', function($scope, $location)
{
var ID = $location.search();
$scope.getClickData=function(ID.dataId){
//REQUEST YOUR DATA
});
});
Note : As we remove (request/angular promise) getClickData() function
from controller1.js and add it to controller2.js .by doing this
controller2 will be responsible for its own data controller2 don't have to
depend on controller1 for data

append response from $http() to div

I'm quite new to Angularjs and I just can't figure out how to append a reply from $http() to a div(or any other element for that matter).
I've been using jQuery for a while and I know how to do it using that library, which is why I'm finding it hard to use Angular for this task.
I have a directive that uses $http.get() to get data from a PHP proxy. I'm trying to append the response from that $http() request to a div.
This is what I got right now:
app.directive('displayArticle', ['$http', '$log', function ($http, $log) {
var replyFromProxy = angular.element('<div></div>');
$http.get('gp-proxy.php').
success(function (data) {
// $log.info(data);
replyFromProxy = angular.element('<div>' + data + '</div>');
}).
error(function (data, status, headers, config) {
// $log.error(data);
// $log.error(status);
// $log.error(headers);
// $log.error(config);
});
return {
restrict: 'E',
templateUrl: 'templates/displayArticle.html',
compile: function (tElem) {
tElem.append(replyFromProxy);
}
};
}]);
displayArticle.html contains an empty div
What am I doing wrong?
Is there an easier or better way to do this?
Edit: What I'm trying to do is use gp-proxy.php to load an external page into my own webpage. The host doesn't allow CORS so this was my back-up plan.
Using ng-include in my template feels too static and not dynamic enough since I'd like to be able to load in different pages depending on what I click on in the original page.

How can I compile data returned from an $http request?

I am having a recurring issue where I am unable to use directives that are included inside of template partials retrieved via $http. I assume that I need to use $compile or $apply to the template in order to get the directives to work. The following code attempts to use $apply on returned data from $http but it doesn't work:
$http({
url: 'get/data',
method: "POST"
})
.success(function (data, status, headers, config) {
$scope.$apply(function () {
$scope.data = data;
});
})
.error(function (data, status, headers, config) { $scope.status = status; });
The returned value (data) is simply a template that contains some HTML that has a few directives in it. If I write
.success(function (data, status, headers, config) { $scope.data = data }
then the template loads, but any directives in the template won't work. So I figured I need to use $apply or $compile to bind the directives to angular. There is clearly something fundamental that I'm missing in my understanding of angular and how directives can be bound to work in dynamically loaded templates. Any help would be much appreciated.
You're correct that you need to use the $compile service to handle directives in dynamically loaded template. $compile processes some html and returns a linking function. When the linking function is called with a scope, it returns the fully compiled and linked template with functioning directives. This template must then be inserted into the live DOM. As zsong points out, this implies that all this should really be done in a directive, which is the domain of DOM manipulation in Angular. In one line:
container.html($compile(loadedHtml)(scope))
container is the element in the DOM that will contain the dynamic template. We set its html to the result of linking the compiled html to the scope.
You could just load template via templateUrl (http://docs.angularjs.org/guide/directive).
The basic idea is that you write you directive in js, it's matching html in separate file which can be included in that directive via templateUrl.

Resources