I get no errors with my current code.
var app = angular.module('mgcrea.ngStrapDocs', ['ngAnimate', 'ngSanitize', 'mgcrea.ngStrap']);
app.controller('MainCtrl', function($scope) {
});
angular.module('mgcrea.ngStrapDocs')
.controller('NavbarDemoCtrl', function($scope, $location) {
$scope.$location = $location;
});
app.controller ('formController',[ '$scope', '$http', function($scope, $http) {
$scope.formData = {};
$scope.processForm = function () {
console.log('Click');
$http({
method : 'POST',
url : '/users/login',
data : $scope.formData
}).success(function(data, status, headers, config) {
console.log(data);
}).error(function() {
console.log("ERROR")
});
}
}]);
use strict;
I confirmed that the url: localhosts/users/login accepts post data via Postman. However, grouping everything together I find that I cannot actually submit the form to the api. I am not sure if there is some conflicting code or what specifically is the issue as I mentioned before I am not currently getting any errors.
Also, here is a paste bin link to the html if there seems to be no issue with the js.
The problem appears to be in your markup. There are a few things to fix.
The first is to specify the name of the Angular module you are using for your application via the ng-app directive. In your case, this appears to be "mgcrea.ngStrapDocs". So your <html> tag becomes:
<html ng-app="mgcrea.ngStrapDocs">
Second, you are not telling Angular to use your controller at all in your markup. In your case, the easiest way to do this it to specify it using ng-controller on your <form> tag:
<form ng-controller="formController" ng-submit="processForm()">
Related
Edit: James P. led me to determine that the issue appears to be with CORS and not necessarily with any of the Angular code. Please read comments below.
I am very new to AngularJS and JS altogether, so I'm sure the answer to this is something simple that I have overlooked so thank you in advance.
I am using Angular Seed and I have created an API that is verified working (as in, I go to my URL:3000/getstuff and it displays queries from my mongodb just fine).
That API returns a JSON format response from a mongodb with 3 key/pairs including id. I am able to view it in browser just fine.
So in Angular seed, very basic view1/view1.js I modified to as such:
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', '$http', function($scope, $http) {
//$scope.test = "test";
//the above works when I bind in view1.html
$http.get('http://x.x.x.x:3000/getstuff').
success(function(response) {
$scope.information = response;
});
}]);
And it is not working as I thought it might. So when I try to bind this response in view1.html with a simple {{information}} it's blank. This code did not break the app either, it still works and I am able to display {{test}} if I uncomment it.
Anyhow, any help would be very much appreciated. And for the record, I have been reading up on this for days and days before posting this. I am just a novice is all.
You need to use angular.copy to copy the data to your $scope variable:
$http.get('http://x.x.x.x:3000/getstuff')
.then(function (response) {
// Success
angular.copy(response.data, $scope.information);
}, function () {
// Failure
});
Then in your view:
<div ng-controller="MainController">
<div ng-repeat="item in information">
<p>{{item.id}}</p>
<p>{{item.type}}</p>
<p>{{item.text}}</p>
</div>
</div>
Where id ,type and text are properties of each item in the Array.
EDIT: Just for completeness the following is a working example, with above html snippet.
(function () {
"use strict";
angular.module("app", []);
angular.module("app").controller("MainController", mainController);
function mainController($scope, $http) {
$scope.information = [];
$http.get("http://api.scb.se/OV0104/v1/doris/en/ssd")
.then(function (response) {
// Success
angular.copy(response.data, $scope.information);
}, function () {
// Failure
});
}
})();
I have an index page wherein I define two controllers. I want to call one main controller always (should be rendered always) and the other is called only for specific sub URL calls. Should I make one nested within another, or I can keep them independent of each other? I don't have access to change routes or anything, only the controller.
Right now when I use the template (HTML) mentioned, it calls/renders both controllers, even though url is say /index
Only for /index/subPage, I want both controllers to be rendering.
/index
/index/subPage
HTML:
<div ng-controller="MainCtl" ng-init=initMain()>
<p> Within ctller2 {{results}} </p>
</div>
<div ng-controller="Ctller2"> <!-- should not be displayed unless /subPage/mainUrl is rendering -->
<p> Within ctller2 {{results}} </p>
</div>
JS:
app.controller('MainCtl', ['$scope', '$http', '$location', function ($scope, $http, $location) {
$http.get('xx/mainUrl').then(function(data) {
$scope.results = someDataJSON;
console.log(someDataJSON);
});
$scope.initMain = function() {
$scope.initMethods();
}
}]);
app.controller('Ctller2', ['$scope', '$http', '$location', function ($scope, $http, $location) {
// This controller gets initialized/rendered/called even when xx/mainUrl is called, and when xx/subPage/mainUrl is called too..
$http.get('xx/subPage/mainUrl').then(function(data) {
$scope.results = someDataJSON;
console.log(someDataJSON);
})
$http.get('xx/subPage').then(function(data) {
$scope.results = data.data;
console.log(data);
})
angular.element(document).ready(function () {
alert('Hello from SubCtl, moving over from main controller to here');
});
}]);
What am I doing wrong? I'm new to Angular.js
You can conditionally initiate a controller using ng-if. So you could try something like this:
<body ng-controller="MainCtrl">
<div ng-controller="ctrl1">{{hello}}</div>
<div ng-controller="ctrl2" ng-if="showCtrl2">{{hello}}</div>
</body>
and then set the value of the variable in a parent controller by checking the current url using $location.path()
var app = angular.module('plunker', []);
app.config(function($locationProvider){
$locationProvider.html5Mode(true);
});
app.controller('MainCtrl', function($scope, $location) {
$scope.showCtrl2 = ($location.path() === 'my path');
});
app.controller('ctrl1', function($scope){
$scope.hello = 'ctrl1 says hello';
});
app.controller('ctrl2', function($scope){
$scope.hello = 'ctrl2 says hello';
});
But it's a bit hacky and for a larger project a more robust solution would require using something like ui.router.
I am trying to use Angular's routing to resolve the necessary objects for the controller scope. I have read a few tutorials on how to do this but I still get an Unknown Provider error. The issue seems to be with project being injected into ProjectDetailCtrl.
app.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config( function ($interpolateProvider, $routeProvider) {
$routeProvider
...
.when('/project/:projectId', {
templateUrl : 'partials/_project_detail.html',
controller: 'ProjectDetailCtrl',
resolve: {
project: function ($route, MyService) {
return MyService.get('projects/', $route.current.params.projectId).then(function(data) {
console.log('VERIFY DATA: ', data);
return data;
});
}
}
controllers.js
.controller('ProjectDetailCtrl', function ($scope, project) {
$scope.project = project;
}
Edit
services.js
.factory('MyService', function ($http, $q) {
var MyService = {
...
get: function (items_url, objId) {
var defer = $q.defer();
$http({method: 'GET',
url: api_url + items_url + objId}).
success(function (data, status, headers, config) {
defer.resolve(data);
}).error(function (data, status, headers, config) {
defer.reject(status);
});
return defer.promise;
},
Edit 2
The issue is apparently not with the Service method, as this also produces the error:
app.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config( function ($interpolateProvider, $routeProvider) {
$routeProvider
...
.when('/project/:projectId', {
templateUrl : 'partials/_project_detail.html',
controller: 'ProjectDetailCtrl',
resolve: {
project: {title: 'foo'}
}
});
})
I can verify my resolve function is being returned properly, but Angular still complains that project is unidentified. What is this issue here? I have tried making my controllers into a module and passing that to the myApp module, but I still get the same Unidentified Provider issue for project.
Note: I am using Angular 1.2.9.
Edit 3: solution
So the issue was this line in my template:
<!-- WRONG: <div ng-controller="ProjectDetailCtrl">-->
<div>
<h2 ng-show="project">Project: <strong>{{ project.title }}</strong></h2>
</div>
Apparently the ng-controller directive cannot be use with resolve.
You forgot to add ngRoute as a dependency for your module. Thats why $routeProvider and $route service are undefined.
Update:
See this example. Problem was in ng-controller directive
You're returning the MyService.get, which is a promise, and then within the result of the promise, you're returning the data.... but to what?
You want to return the promise, but not the original promise... so you create your own promise using $q, and Angular will wait and resolve it for you before loading your route.
project: function ($route, MyService) {
var deferred = $q.defer();
MyService.get('projects/', $route.current.params.projectId).then(function(data) {
console.log('VERIFY DATA: ', data);
deferred.resolve(data);
});
return deferred.promise;
}
Or, assuming MyService.get returns a promise, you should be able to just do
project: function ($route, MyService) {
return MyService.get('projects/', $route.current.params.projectId);
}
And obviously inject $q into config
This question has been asked before, therefore it's a possible duplicate.
The top answer points out usage of controllers within markup to have caused this.
Search your codebase (markup or templates to be exact) for the term ng-controller.
Verify if there is a matching controller, as in this case ProjectDetailCtrl
Remove it from the markup
It solved the problem in my case.
I have created a simple Angular JS $routeProvider resolve test application. It gives the following error:
Error: Unknown provider: dataProvider <- data
I would appreciate it if someone could identify where I have gone wrong.
index.html
<!DOCTYPE html>
<html ng-app="ResolveTest">
<head>
<title>Resolve Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"> </script>
<script src="ResolveTest.js"></script>
</head>
<body ng-controller="ResolveCtrl">
<div ng-view></div>
</body>
</html>
ResolveTest.js
var rt = angular.module("ResolveTest",[]);
rt.config(["$routeProvider",function($routeProvider)
{
$routeProvider.when("/",{
templateUrl: "rt.html",
controller: "ResolveCtrl",
resolve: {
data: ["$q","$timeout",function($q,$timeout)
{
var deferred = $q.defer();
$timeout(function()
{
deferred.resolve("my data value");
},2000);
return deferred.promise;
}]
}
});
}]);
rt.controller("ResolveCtrl",["$scope","data",function($scope,data)
{
console.log("data : " + data);
$scope.data = data;
}]);
rt.html
<span>{{data}}</span>
The problem is that you have ng-controller="ResolveCtrl" on your body tag in index.html when also in your $routeProvider you specify the same controller for rt.html. Take out the controller definition from your body tag and just let the $routeProvider take care of it. It works great after that.
According to the angularjs documentation for $routeprovider the resolve object is a map from key (dependency name) to factory function or name of an existing service. Try this instead:
var myFactory = function($q, $timeout) { ... };
myFactory.$inject = ['$q', '$timeout'];
$routeProvider.when("/",{
templateUrl: "rt.html",
controller: "ResolveCtrl",
resolve: {
data: myFactory
}
});
By adding data to the definition of the controller your telling angular that you expect to inject a service or factory here yet you don't have a data service or factory thus the error. To use the data variable you have all you need from the $scope.data line. So to fix this you need to remove the data injection from your controller call.
var rt = angular.module("ResolveTest",[]);
rt.config(["$routeProvider",function($routeProvider)
{
$routeProvider.when("/",{
templateUrl: "rt.html",
controller: "ResolveCtrl",
resolve: {
data: ["$q","$timeout",function($q,$timeout)
{
var deferred = $q.defer();
$timeout(function()
{
deferred.resolve("my data value");
},2000);
return deferred.promise;
}]
}
});
}]);
rt.controller("ResolveCtrl",["$scope", function($scope)
{
$scope.data = "";
}]);
If you want to have a data provider add a factory something like
rt.factory('data', ['$http', function($http){
return {
// Functions to get data here
}
}]);
Then in your controller call the appropriate function from this factory.
Also as the others have pointed out you don't need the controller both in your route and in an ng-controller (this will nest your controller in your controller if you inspect the scopes).
If you must use resolve you still need a factory as resolve will just point to the proper factory which needs to be declared separately.
I have the following Angular function:
$scope.updateStatus = function(user) {
$http({
url: user.update_path,
method: "POST",
data: {user_id: user.id, draft: true}
});
};
But whenever this function is called, I am getting ReferenceError: $http is not defined in my console. Can someone help me understanding what I am doing wrong here?
Probably you haven't injected $http service to your controller. There are several ways of doing that.
Please read this reference about DI. Then it gets very simple:
function MyController($scope, $http) {
// ... your code
}
I have gone through the same problem when I was using
myApp.controller('mainController', ['$scope', function($scope,) {
//$http was not working in this
}]);
I have changed the above code to given below. Remember to include $http(2 times) as given below.
myApp.controller('mainController', ['$scope','$http', function($scope,$http) {
//$http is working in this
}]);
and It has worked well.
Just to complete Amit Garg answer, there are several ways to inject dependencies in AngularJS.
You can also use $inject to add a dependency:
var MyController = function($scope, $http) {
// ...
}
MyController.$inject = ['$scope', '$http'];