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

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.

Related

Dynamic partial arguments in AngularJS routing

I'm working with an angularjs site and have a background with working with routes in Rails and also Laravel in php. With routes in Laravel we could dynamically create a set of routes similar to:
foreach($cities as $city):
Route::get($city.'/hotels');
Route::get($city.'/{slug}');
endforeach;
Here we defined series of seperate routes in Laravel which technically do look the same except for the value of city and slug.
I'm finding angularJS a bit limited in defining routes in this case. Frankly am a bit lost here.
UPDATE
I've made some modifications here - basically I set up a service which retrieves assets from my database such as in this case a list of cities and categories. I'm trying to do this:
If {slug} is in the array of categories retrieved from my API, then use my ListController and list view but if its not then instead use my SingleVenueController and single view. Here's my code at the moment but its not working :(
appRouteProvider.when('/:city/:slug', {
templateUrl : function(sharedParams, $routeParams){
t = sharedParams.getCurrentPageType($routeParams);
if(t=='list'){
return '../../app/templates/list.html';
}
if(t=='single'){
return '../../app/templates/single.html';
}
},
controller : function(sharedParams, $routeParams){
t = sharedParams.getCurrentPageType($routeParams);
if(t=='list'){
return 'ListsController';
}
if(t=='single'){
return 'SingleController';
}
},
resolve:{
sharedParamsData:function(sharedParams){
return sharedParams.promise;
},
}
})
In the above sharedParams is a service and the getCurrentPageType just checks the url slug to decide what controller to send back - but its not really working at all :(
How about defining a single route with a paramater ?
In angularjs v1.x you can defined as many routes you want with as many params xor query
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/city/:slug', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
// you can also retrieve some data as a resolved promise inside your route for better performance.
}
})
ref: https://docs.angularjs.org/api/ngRoute/service/$route
appRouteProvider.when('/:city/:slug', {
templateUrl : 'dafault.html',
controller : 'DefaultController',
resolve:{
factory: function($routeParams, $http, $location, sharedParams){
var city = $routeParams.city;
var slug = $routeParams.slug;
var deferred = $q.defer();
sharedParams.getCurrentPageType($routeParams).then(function(t) {
if(t=='list'){
$location.path('/' + city + '/' + slug + '/list');
deferred.resolve();
}
else if(t=='single'){
$location.path('/' + city + '/' + slug + '/single');
deferred.resolve();
} else {
deferred.reject();
}
});
return deferred.promise;
},
}
});
appRouteProvider.when('/:city/:slug/list', {
templateUrl: '../../app/templates/list.html',
controller: 'ListsController',
});
appRouteProvider.when('/:city/:slug/single', {
templateUrl: '../../app/templates/single.html',
controller: 'SingleController',
});
You can do it with separate routes. The idea is when user hits the main route it resolves first with the data from the backend. If the condition is met, resolve function will redirect to specific route if not it wont pass
Services in Angular cannot be injected in the configuration phase since they become available only in the run phase of an Angular application.
There is however a trick to load $http service in the config phase which you can use to load your cities/categories and set up your routes. Meanwhile, since controllers aren't registered up until the run phase, you may use the $controllerProvider to register your controllers beforehand in the configuration phase:
app.config(function ($routeProvider, $controllerProvider) {
$controllerProvider.register('ListController', ListController);
$controllerProvider.register('SingleController', SingleController);
// wire the $http service
var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');
...
});
You can now call your API to get the cities (or whatever else) and iterate while registering each route:
...
// fetch the cities from the server
$http.get('/cities')
.then(function (response) {
var cities = response.data;
for(var i = 0; i < cities.length; i++){
$routeProvider
// assuming each city object has a `name` property
.when('/' + cities[i]['name'] + '/:slug', {
templateUrl: getTemplate(cities[i]['name']),
controller: getController(cities[i]['name'])
})
}
});
...
Note that I'm using the getTemplate and the getController methods which return the templateUrl and the relevant controller name strings respectively using an ordinary switch expression. You can choose your own approach.
Plunkr Demo
Note:
While a function with the templateUrl route options property does work with setting up a custom template, but when you use a function alongside the controller property, Angular will consider it as the constructor for the controller. Therefore, returning the name of the controller in that function won't work.
As Ahmad has already pointed out in his answer, if you pass a function to controller it is considered as a constructor for the controller.
Also you can't get a service injected dynamically in config block of your app.
So what you can do is, move your sharedData service in separate app (in my code below I've used appShared as a separate app where this service is defined) and then access it using angular.injector. This way you don't have to define it as a parameter to templateUrl / controller functions.
Btw, you can't pass custom parameters to templateUrl function (ref: https://docs.angularjs.org/api/ngRoute/provider/$routeProvider)
If templateUrl is a function, it will be called with the following
parameters:
{Array.<Object>} - route parameters extracted from the current $location.path() by applying the current route
Now for the controller, use $controller to dynamically load either ListsController or SingleController based on your condition.
Once that is loaded, extend your current controller (defined by your controller function) using angular.extend so that it inherits all the properties and methods of the dynamically loaded controller.
Check the complete code here: http://plnkr.co/edit/ORB4iXwmxgGGJW6wQDy9
app.config(function ($routeProvider) {
var initInjector = angular.injector(['appShared']);
var sharedParams = initInjector.get('sharedParams');
$routeProvider
.when('/:city/:slug', {
templateUrl: function ($routeParams) {
console.log("template url - ");
console.log($routeParams);
var t = sharedParams.getCurrentPageType($routeParams);
console.log(t);
if (t == 'list') {
return 'list.html';
}
if (t == 'single') {
return 'single.html';
}
},
controller: function ($routeParams, $controller, $scope) {
//getController(cities[i]['name'])
console.log("controller - ");
console.log($routeParams);
var t = sharedParams.getCurrentPageType($routeParams);
console.log(t);
if (t == 'list') {
angular.extend(this, $controller('ListsController', { $scope: $scope }));
}
if (t == 'single') {
angular.extend(this, $controller('SingleController', { $scope: $scope }));
}
}
});
});

change query params on basis of on page filter angularjs

i have a design issue while working with angular. Need suggestions on it.
I have a page which loads based on route. Now on the page i have some filters which controls the data like price range and date. these filters will set query param in url. so state + query params will decide the data. And on every change of filters these query params should change and accordingly pages should be loaded. each filter has its own directive.
Now the problem is when first time i am routing to a state. and these filters are generated by directives for the first time :
how i will bind them to url query param. and then these query param should be passed to routeProvider and then to controllers which will fetch the data.
when page is loaded how i will bind these filters so that on change again query params are changed and new data is fetched and page is populated.
how to bind these query params in two way direction.
My code snippet :-
route :-
decorpot.config(['$routeProvider', '$provide', function($routeProvider, $provide){
$provide.decorator('ngViewDirective', function($delegate) {
var directive = $delegate[0];
directive.replace = true;
return $delegate;
});
$routeProvider.when('/', {
templateUrl: 'resources/partials/home.html',
controller: 'DecorpotCtrl'
}).when('/imageListSpace/:param', {
templateUrl: 'resources/partials/imageList.html',
controller: 'ImageListController'
})
.otherwise({
redirectTo: '/'
});
}]);
Controllers -
decorpotCtrls.controller('ImageListController', [ '$scope', '$routeParams', 'interiors', function($scope, $routeParams, interiors ) {
interiors.getImages($routeParams.param).success(function(data) {
$scope.imageList = data;
});
} ]);
filter directive -
decortDirectives.directive("priceRange", function() {
$("#priceRange").ionRangeSlider({
type : "double",
min : 100000,
max : 300000,
prefix : "Rs.",
prettify_enabled: true,
});
});

AngularJS - Page redirecting to some other page in angular js while trying to get parameter from url

Here's my controller code
.when('/showprofile/:UserID', {
templateUrl: 'resources/views/layout/showprofile.php',
controller: 'ShowOrderController',
})
I am passing the parameter by url.
I am trying to access this page by the url directly like this
http://192.168.1.58/myapp/#/showprofile/8
But it is redirecting me to
http://192.168.1.58/myapp/#/showprofile/:UserID
How can i get the url value in my view ?
Here is my app.js and here is my authCtrl.js
Try this in your controller, it will return the object based on url value then we can get the respected value like this
//it will return the object
console.log($routeParams);
//get the specific url value like this
console.log($routeParams.UserID);
or
console.log($route.current.params.UserID);
Yes possible but you have to inject the $state in your controller and get
if you use $state means
console.log($state.params.userID);
Try this...
var sampleApp = angular.module('sampleApp', []);
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/ShowOrder/:orderId', {
templateUrl: 'templates/show_order.html',
controller: 'ShowOrderController'
});
}]);
sampleApp.controller('ShowOrderController', function($scope, $routeParams) {
$scope.order_id = $routeParams.orderId;
});
Right, you have something like this in app.js:
.when('/showprofile/:UserID', {
templateUrl: 'resources/views/layout/showprofile.php',
controller: 'authCtrl',
})
That means that authCtrl is assigned to this view.
So, it's neccessary to inject routeParams to authCtrl( remember about dependency injection in javascript ) :
app.controller('authCtrl', ['$scope','$rootScope','$routeParams','$location', '$http', 'Data', function ($scope, $rootScope, $routeParams, $location, $http, Data) {
$scope.myVar = $routeParams.UserID;
console.log('UserID: ',$scope.myVar);
/* (...) */
}]);
Could you tell me, if this change, logs UserID in console? Or is empty?
If it logs, then everything works fine and you can use service to pass this variable between various controllers.

create basic object with $resource

I have been all over the tutorial sites and couldn't get this working
I'm trying to make an angular app that works over the REST with my server(I downloaded this and managed to get it working but I started a new one from scratch to understand everything better). making the REST server was the easy part since I'm a php guy, but I'm not so familiar with angular part.
I made a simple directory with yeoman and put my REST server next to it in another folder, so I have :
root
------app with all angular code here
------engine which is a yii2 framework
in app/script/app.js I have:
'use strict'; // BTW what is this line doing?
var app = angular
.module('gardeshApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/post/index' , {
templateUrl: 'views/post/index.html',
controller : 'PostList'
})
.otherwise({
redirectTo: '/'
});
});
I wanted make some kind of Model object to put received data in, so I created a Post model like :
app.factory('Post' , ['$resource'] , function($resource){
var Post = $resource('http://localhost/testApp/engine/web/post/:id' , {id : '#id'} , {update: {method: 'PUT'}});
angular.extend(Post.prototype , {
save: function (values) {
if (values) {
angular.extend(this, values);
}
if (this.id) {
return this.$update();
}
return this.$save();
}
});
});
and a controller to fetch the data:
app
.controller('PostList', ['$scope', '$http' , '$resource',
function($scope, $http) {
// $http.get('http://localhost/testApp/engine/web/post').success(function(data){
// console.log(data); // this works fine and gets the json ed data
// });
var posts = new Post();
console.log(posts.query());
}]);
I don't want to call $http.get myself, I want to make it dynamic but the Error says Post is not defined.
how can I make a proper Post Object to represent the model I'm fetching?
You may do something like this:
app.factory('Post' , ['$resource'] , function($resource){
var Post = $resource('http://localhost/testApp/engine/web/post/:id',
{
update: {method: 'PUT'}
}
);
return Post;
});
And,
app.controller('PostList', ['$scope', '$http' , 'Post',
function($scope, $http, Post) {
console.log(Post.query());
}]);
You need to return your built object in a factory in order to make it dependency-injectable later. Then in your controller, you need to declare that your want Post, and Angular will inject it for you.

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