GET requests with submit forms using angularjs - javascript

So after learning a bit of AngularJS I was able to get a controller to call an API and store the results in a variable, which is then displayed on my page (whew...). If I go to:
http://127.0.0.1:3000/#/search
I see the page with the submit form but without the results, and if I go to:
http://127.0.0.1:3000/#/search?query=deep&learning
I see the page with the submit form + the results for the "deep & learning" query. The problem is: I have to enter "?query=deep?learning" manually, I'm unable to use the submit form to get there. I use this code:
<form name='input' action='#search' method='get'>
<div class='input-group'>
<input type='text'
class='form-control'
placeholder='Enter query.'
name='query'>
<div class='input-group-btn'>
<button class='btn btn-default' type='submit'><i class='fa fa-search'></i></button>
</div>
</div>
</form>
With this submit form, if I enter "deep & learning" in the form, I get to
http://127.0.0.1:3000/?query=deep&learning#/search
How do I change my code so entering "deep & learning" would get me to:
http://127.0.0.1:3000/#/search?query=deep&learning
?
Thank you
UPDATE1: code for routes:
var myApp = angular.module('myApp', ['ngRoute'])
.factory('myQuery', ['$http', function($http) {
var doRequest = function(query) {
return $http({
method: 'GET',
url: 'http://127.0.0.1:3000/api/v0/docs?search=' + query
});
};
return {
results: function(query) { return doRequest(query); }
};
}]);
myApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
.when('/search', {
templateUrl : 'pages/search.html',
controller : 'searchController'
});
});
myApp.controller('mainController', function($scope) {
// ...
});
myApp.controller('searchController', ['$scope', '$routeParams', 'myQuery', function($scope, $routeParams, myQuery) {
myQuery.results($routeParams.query)
.success(function(data, status, headers) {
$scope.count = data.count;
$scope.results = data.results;
});
}]);

It should simply a matter of changing the action attribute value to get the URL format you want.
In other words:
<form name='input' action='search' method='get'>
Note that the destination URI is no longer prefixed with a hash.
When it is prefixed with a hash as you have it at the moment, it's actually equivalent to directing the submission to the root (i.e. '/') using search as the page anchor.

Related

angularjs ui-router nested states new controller not working

I'm stuck with nested states in the ui-router.
I'm rendering a page with regions, countries and people per country
The index.html has three regions as link, EMEA APAC and AMER
the part of the index page has:
<a ui-sref="territory({territory: 'amer'})">AMER</a> <a ui-sref="territory({territory: 'emea'})">EMEA</a> <a ui-sref="territory({territory: 'apac'})">APAC</a>
<ui-view></ui-view>
when the link is clicked, the countries are returned by a $http.post action and displayed by /views/countries.html as:
<h1>This is countries</h1>
<br>
Teritory: {{region}}
<div ng-repeat='country in countries'>
<a ui-sref=".support({country: '{{country}}'})">{{country}}</a ui-sref>
</div>
This is working so far! so I have a .support link on each country.
The problem is now, when I click the link, the state is accepted...cause it is loading the templateURL, but it seems that the controller specified in that state is not loaded.
the angularjs code:
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'supportCtrl'
})
.state('territory', {
url: '/territory/:territory',
templateUrl: 'views/countries.html',
controller: 'countryController'
})
.state('territory.support',{
url: '/:country',
templateUrl: 'views/supporter.html',
controller: 'supportController'
})
});
the support controller is writing a console.log entry...but nothing happens.
the controllers:
supportApp.controller('countryController',['$scope', 'supportService', '$location', '$stateParams', function($scope, supportService, $location, $stateParams){
$scope.fromTerritory = $stateParams.territory;
$scope.getCountries = function(){
var countries = supportService.getCountries($scope.fromTerritory);
countries.then(function(response){
if(response.data.error){
$scope.error = true;
$scope.message = response.data.message;
}
else{
console.log('response OK');
$scope.region = $scope.fromTerritory;
$scope.countries = response.data;
}
});
}
$scope.getCountries();
}]);
supportApp.controller('supportController',['$scope', 'supportService', '$location', '$stateParams', function($scope, supportService, $location, $stateParams){
console.log('in the supportController');
var test = function(){
console.log('supportController country: '+$stateParams.country);
}
test();
}]);
I'm probably doing something wrong here.
The goal is clicking the country and then displaying names of the people belonging to that specific country.
If it's not clear, I can provide more info where needed. But for now it seems that the controller (supportController) for the nested state (.territory.support) is not running / loaded
thank you!
Ok,
I have my answer for now...
because I did not use the <ui-view></ui-view> on the supporter.html the controller was not 'needed' and did not load.
after adding the the consol.log is showing the log entries.

AngularJS : How to pass multiple parameters to controller through ng-href?

I've a table containing edit button to update the record. When I'm passing single id to ng-href its working fine and opening form page:
Ex: In my index.html table
<a class="btn btn-warning" ng-href="#/provider/{{row._id}}">Edit</a>
But I want to pass one more parameter along with row._id to ng-href like:
<a class="btn btn-warning" ng-href="#/provider/{{row._id}}/collectionName/{{collectionName}}">Edit</a>
Its not working and redirecting to home page.
Here's my controller:
$timeout(function () {
if ($routeParams.id !== undefined) {
$http.get('/providerlist/'+$routeParams.id, {
params:{
id:$routeParams.id,
collectionName:$routeParams.collectionName
}
}).success(function (response) {
alert(response);
$scope.providerList = response;
$scope.id = response['_id'];
});
}
});
app.js for routing:
var ProviderApp = angular.module('ProviderApp', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home/index.html',
controller: 'HomeController',
controllerAs: 'home'
})
.when('/provider', {
templateUrl: 'templates/provider/index.html',
controller: 'ProviderController',
controllerAs: 'provider'
})
.when('/provider/:id', {
templateUrl: 'templates/provider/form.html',
controller: 'ProviderController',
controllerAs: 'provider'
})
.otherwise({
redirectTo: '/home'
});
}]);
Here what exactly I want to do is after clicking on edit button it should redirect to form.html with parameter/data of id and collectionName
Any help would be appreciated.
If you want to use multiple params in ng-href you should also update your route url in app.js.
when you used multiple parameters in ng-href but no route matching with this route then worked otherwise route that redirect to home.
you can try it.
in html:
<a class="btn btn-warning" ng-href="#/provider/{{row._id}}/collectionName/{{collectionName}}">Edit</a>
add a route in app.js like
.when('/provider/:id/collectionName/:cName', {
templateUrl: 'templates/provider/form.html',
controller: 'YourController'
});
and in controller need to change like:
$http.get('/providerlist/'+$routeParams.id +'/collectionName/'+ $routeParams.cName)
.success(function (response) {
alert(response);
$scope.providerList = response;
$scope.id = response['_id'];
});
so server side route should be like: /providerlist/:id/collectionName/:cName
The path in ngRoute path can contain named groups starting with a colon and ending with a star like :name* , All characters are eagerly stored in $routeParams under the given name when the route matches.
For example, routes like : /color/:color/largecode/:largecode*/edit
For this sample URL : /color/brown/largecode/code/with/slashes/edit
And extract:
color: brown
largecode: code/with/slashes.
So in your case it the Route will be
.when('/provider/:id*\/collectionName/:collectionName*\', {
templateUrl: 'templates/provider/form.html',
controller: 'ProviderController',
controllerAs: 'provider'
})
This will ensure that even if there are special characters and forward slashes in your resultant href link you are redirected to proper controller and page...

angular promise - on submit gets "Error: args is null $parseFunctionCall"

I am currently following this tuto on MEAN.js : https://thinkster.io/mean-stack-tutorial/ .
I am stuck into the end of "Wiring Everything Up", I am completlty new to angular so I am not pretending I understood everything I did. Here is the situation :
We are using the plugin ui-router.
First here is the html template :
<form name="addComment" ng-submit="addComment.$valid && addComment()"novalidate>
<div class="form-group">
<input class="form-control" type="text" placeholder="Comment" ng-model="body" required/>
</div>
<button type="submit" class="btn btn-primary">Comment</button>
</form>
The error "Error: args is null $parseFunctionCall" occurs only when I submit the form
Then, here is the configuration step for this page :
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('posts', {
url : '/posts/{id}',
templateUrl: '/posts.html',
controller : 'PostsCtrl',
resolve : {
post: ['$stateParams', 'posts', function ($stateParams, posts) {
return posts.get($stateParams.id);
}]
}
});
$urlRouterProvider.otherwise('home');
}]);
There, is the controller :
app.controller('PostsCtrl', ['$scope', 'posts', 'post',
function ($scope, posts, post) {
$scope.post = post;
$scope.addComment = function () {
posts.addComment(post._id, {
body : $scope.body,
author: 'user'
}).success(function (comment) {
$scope.post.comments.push(comment);
});
$scope.body = '';
};
$scope.incrementUpVote = function (comment) {
posts.upvoteComment(post, comment);
};
}]);
And Finally, the factory where the posts are retrieved from a remote webservice
app.factory('posts', ['$http', function ($http) {
var o = {
posts: []
};
o.get = function (id) {
return $http.get('/posts/' + id).then(function (res) {
return res.data;
});
};
o.addComment = function (id, comment) {
return $http.post('/posts/' + id + '/comments', comment);
};
return o;
}]);
I've only given the parts that I think are relevant.
I suspect that the problem is comming from the promise and the scope which have been unlinked. I searched about promises but I think that ui-router is doing it differently.
I tried some $watch in the controller but without succeding.
Has anyone some idea about that ? Thank you in advance
The form name addComment (used for addComment.$valid) and the function addComment added to the scope are clashing with each other, rename one or the other.
See the Angular docs for the form directive:
If the name attribute is specified, the form controller is published
onto the current scope under this name.
As you are manually also adding a function named addComment, it is using the wrong one when evaluating the ng-submit.

AngularJS: How to change url in $http.get on select event

I have customers.php file which produce json data. List of json data are changing when we change variable in the url like this
customers.php?var=5
In AngularJS I have made html file with two separate part. 1st part is a select options with specific values. 2nd part is part who shows json data. It is clear that 2nd part use $http.get(url) where url is customers.php?var=selected_number in controller.
How can I change url in controller which use $http.get when user select specific options in < select > ... < / select > html file.
Footnote: Here is example of controller file
var Pajsije = angular.module('CodeOverflow', ['ngRoute']);
Pajsije.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/viewa', {
templateUrl : 'viewa.html',
controller : 'ViewAController'
})
// route for the about page
.when('/viewb', {
templateUrl : 'viewb.html',
controller : 'ViewBController'
})
// route for the contact page
.when('/viewc', {
templateUrl : 'viewc.html',
controller : 'ViewCController'
})
.otherwise({
redirectTo: '/viewa'
});
});
// create the controller and inject Angular's $scope
Pajsije.controller('ViewAController', function($scope) {
// create a message to display in our view
$scope.message = 'Good look!';
});
Pajsije.controller('ViewBController', function($scope) {
$scope.message = 'Look about page.';
});
Pajsije.controller('ViewCController', ['$scope','$http', '$templateCache', function($scope, $http, $templateCache) {
$scope.myChange = function() {
$http({method: 'GET', url: '../json-data/customers.php?idstudm=12', cache: $templateCache}).success(function (response) {$scope.names = response.records;});
};
}]);
Try $rootScope to set the variable part of the URL in the controller whenever the selection in the UI (HTML Page) is made (querypart).
$rootScope.variableURL = "customers.php?var=" + $scope.selected_number; Append this to the URL while sending $http request. Please inform me if I didn't understand the requirement properly.
We already know that $rootScope is accessible across all controllers and can be used for smaller data carrying across controllers and services.
Use should bind selectbox to a scope model using ngModel directive and use this model in controller. Something like this:
<select ng-model="number" ng-change="myChange()">
<option value="3">3</option>
<option value="3">10</option>
</select>
Controller:
Pajsije.controller('ViewCController', ['$scope', '$http', '$templateCache', function ($scope, $http, $templateCache) {
$scope.myChange = function () {
$http({
method: 'GET',
url: '../json-data/customers.php?idstudm=' + $scope.number,
cache: $templateCache
}).success(function (response) {
$scope.names = response.records;
});
};
}]);
I read your question. I think you have problem with separated files. I guess, because you are using AngularJS, you are using angular-route for automatic routing. So, for that reason you are probably using file like main.html which is include customers.html with routing management.
If in that file you have mechanism which will present data when routing happens, the data will not be presented in main file with ng-controller when user click on particular data to select. (not all data, only data which are in myChange function)
Best regards.

AngularJS Controller depending on URL parameter

EDIT: Added $routeProvider and $routeParams, but $routeParams.productId is always undefined. It was my initial try, but I thought it was the wrong way. Anyway it does not work for the moment.
I start to learn AngularJS and I have a very simple question :
Depending on ID contained in URL, I would like to display different BD record.
...
<div ng-app=MyApp>
<div ng-controller="MyCtrl">
{{ record }}
</div>
</div>
...
My Javascript file :
var MyApp = angular.module("MyApp",[]);
MyApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/get/:productId', {
controller: 'MyCtrl'
});
}])
MyApp.controller('MyCtrl',['$scope','$routeParams','$http',
function($scope,$routeParams,$http) {
$http.get("/get/"+$routeParams.productId).success(function(data) {
$scope.record = data;
});
}])
I tried to use $routeProvider and $routeParams without success.
Thank you in advance,
Bill
you need 2 things , the $routeParams injected in your controller and create a valid route with the get method
MyApp.controller('MyCtrl',['$scope','$http',"$routeParams",
function($scope,$http,$routeParams) {
$http.get("/get/"+$routeParams.productId).success(function(data) {
$scope.record = data;
});
};

Categories

Resources