Sending a $routeParam to the server through a service Angular - javascript

You will have to bear with me because I am a self-taught noob.
I have a php page on my server that need a $_get variable to sort the data on the server side rather than the client. I am using routeParams in Angular for the variable to send over. This works, however it only works when you refresh the webpage. Please can someone help me as my head hurts from hitting the wall.
Controller:
app.controller('JuiceController', ['$scope', 'juices', function($scope, juices) {
juices.success(function(data){
$scope.juices = data;
});
}]);
Service:
app.factory('juices', ['$http', '$routeParams',function($http, $routeParams) {
return $http.get('http://madcow-app.dev/application/backend/api/products.php', {
params: {prod: $routeParams.prod}
})
.success(function(data) {
return data;
})
.error(function(err){
return err;
});
}]);
Html output (juice view):
<div class="juice-wrap" ng-repeat="juice in juices">
<div class="juice-img"><img ng-src="{{ juice.imgpath }}" width="163" height="176" alt=""/></div>
<div class="juice-rght">
<div class="juice-title">{{ juice.name }}</div>
<div class="juice-desc">{{ juice.descrip }}</div>
Route provider
$routeProvider
.when('/', {
templateUrl: 'script/views/home.html'
})
.when('/categories/', {
controller: 'CatController',
templateUrl: 'script/views/categories.html'
})
.when('/juice/:prod', {
controller: 'JuiceController',
templateUrl: 'script/views/juice.html'
})
.when('/events/', {
controller: 'EventController',
templateUrl: 'script/views/events.html'
})
.when('/qr/', {
templateUrl: 'script/views/qr.html'
})
.when('/feedback/', {
templateUrl: 'script/views/feedback.html'
})
.otherwise({
redirectTo: '/'
php function outputs json (this is outputted to the php controller below and takes the category id as a variable:)
return json_encode($results);
To the php controller (this is the page that the angular service/factory pulls the json array of products from:
<?php
include "../../init.php";
if (isset($_GET['prod']))
{
echo $MC->Api->getProductsApi($_GET['prod']);
}
else
{
echo 'error';
}
This is the category html:
<div class="cat-btn" ng-repeat="cat in cats">
<a href="#/juice/{{cat.catid}}">
<img ng-src="{{ cat.imgpath }}" width="363" height="195" alt=""/>
<div class="cat-btn-text"> {{ cat.name }} </div>
</a>
basically what I want to achieve is when a user clicks a category in the frontend, angular routes to the product view using the category id as a filter for the php function to populate the json output with only the juices in that category.
I'm not sure if I should be doing it this way around, or whether I need to hit it from another angle. Please bear in mind that i am a complete javascript noob and laymans would be great for the answer.
Thank you in advance.....

Factory:
app.factory('juices', [
'$http', '$routeParams', function ($http, $routeParams) {
var self = this;
function getJuices() {
$http.get('http://madcow-app.dev/application/backend/api/products.php', {
params: {prod: $routeParams.prod}
})
.success(function (data) {
self.juices = data.data;
})
.error(function (err) {
});
}
return {
getJuices: getJuices,
juices: self.juices
}
}
]);
Controller:
app.controller('JuiceController', [
'$scope', 'juices', function ($scope, juices) {
juices.getJuices();
$scope.$watch(function () {
return juices.juices
}, function (newJuices, oldJuices) {
// This is triggered when juices.juices changes
// newJuices containes the juices retrieved from server
// This is needed because it is asynchronous
});
}
]);

Related

AngularJS $http.get with ngRoute how to list details

Maybe someone will help me. I write an app in angularjs, I have a file named list.html which retrieves a list of posts from jsonplaceholder and lists them, with a link to the details of the post. In $ routeParams, I pass the id of the selected one and pick it up. Unfortunately, I have no idea how to download the details of a post and display them in the details.html file. If I want to remove something for example, I write for example $ scope.deletePost as a function and give an id, but how to list details I have no idea.
//routing.js
var myApp = angular.module('myApp', ["ngRoute"])
myApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/test', {
templateUrl: '/event/example.html',
controller: 'exampleController'
}, null)
.when('/list', {
templateUrl: '/event/list.html',
controller: 'exampleController'
}, null)
.when('/test-list', {
templateUrl: '/test/list.html',
controller: 'testController'
}, null)
.when('/test/:id', {
templateUrl: '/test/details.html',
controller: 'testController'
}, null)
}
]);
//controller.js
angular.module('myApp').controller('testController', function ($scope, $http, $routeParams) {
$http.get('https://jsonplaceholder.typicode.com/posts').then(function (response) {
$scope.posts = response.data;
});
$scope.id = $routeParams.id;
});
//details.html
<div data-ng-controller="testController">
{{data}}
</div>
//list.html
<div data-ng-controller="testController">
<ul>
<li ng-repeat="post in posts">
Tytuł: {{post.title}} <a href="#!test/{{post.id}}" >Show</a>
</li>
</ul>
</div>
Check out this plunkr.
You just need to pass the details using ng-href and then catch in the controller using $routeParams. I hope this would help you with what you were looking for.
var app = angular.module( 'mainApp', ['ngRoute'] );
app.config( function( $routeProvider ) {
$routeProvider
.when( '/main', {
templateUrl: 'list.html',
controller: 'listCtrl'
})
.when('/detail/:id', {
templateUrl: 'detail.html',
controller: 'detailCtrl'
})
.otherwise({
redirectTo: '/main'
});
});
app.controller( 'listCtrl', function( $scope, $http) {
$http.get('https://jsonplaceholder.typicode.com/posts')
.then(function(res){
$scope.data = res.data;
})
});
app.controller( 'detailCtrl', function( $scope,$http, $routeParams) {
$scope.id = $routeParams.id;
$http.get('https://jsonplaceholder.typicode.com/posts/'+$scope.id)
.then(function(res){
$scope.data = res.data;
})
});

AngularJS not routing properly

I am learning Angular, so here is my testapp : http://enrolin.in/test/#/students
Now here I want to search the database by name. So I created the php that returns exactly what I need. Here is the php : http://enrolin.in/test/login.php?p=fetchbyname&&name=ak You have to replace name in the url to anything you need to search. I also created a partial page that returns absolutely correct results, here is the page: http://enrolin.in/test/#/studentSearch/ak Everything was fine till now But here is the problem:
When I try to search in http://enrolin.in/test/#/students , angularJS does not route me to something like http://enrolin.in/test/#/studentSearch/ak but instead to the default that I have set in $routeProvider
Here is my angularJS (I have removed some unimportant code):
The route provider:
.config(function ($routeProvider) {
$routeProvider
.when("/students/:id", {
templateUrl: "templates/studentDetails.html",
controller: "studentDetailsController"
})
.when("/studentSearch/:name", {
templateUrl: "templates/studentSearch.html",
controller: "studentSearchController"
})
.otherwise({
redirectTo: "/home"
})
})
The Controller that passes the link:
.controller("studentsController", function ($scope, $http, $route,$location) {
$scope.searchStudent=function(){
if($scope.name){
$location.url("/studentsSearch/" + $scope.name);
}
else{
$location.url("/studentsSearch/");
}
}
$scope.reloadData=function(){
$route.reload();
}
$http.get("http://enrolin.in/test/login.php?p=fetchall")
.then(function (response) {
$scope.students = response.data;
})
})
The controller that fetches data and displays:
.controller("studentSearchController", function ($scope, $http, $routeParams) {
if($routeParams.name)
{
$http({
url: "http://enrolin.in/test/login.php?p=fetchbyname&&name=",
method: "get",
params: { name: $routeParams.name }
}).then(function (response) {
$scope.studs = response.data;
})
}
else
{
$http.get("http://enrolin.in/test/login.php?p=fetchall")
.then(function (response) {
$scope.students = response.data;
})
}
})
Previously everytime I wanted to put a link in html to route I used to write like courses But now when I want to put it in the function instead, I am not sure what to write. Please Help.
Hi #AkhilEshKhajuria,
You are not using the same name what you have mentioned in the routing config. Routing name is "/studentSearch/:name?" but you have used in the function as "/studentsSearch/".
Please try replacing $location.url("/studentsSearch/" + $scope.name); with $location.path("/studentsSearch/" + $scope.name);
Correct the naming issue and it should work.
I tried this and it works fine.

How should I get the data from JSON into another angular js controller?

I'm new to AngularJS and stuck on below code.
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "partials/home.html",
controller: "mainController",
})
.when('/products', {
templateUrl: "partials/productlist.html",
//controller: "ProductController",
})
.when('/product/:prodID', {
templateUrl: "partials/product.html",
controller: "viewController",
})
.when('/contact', {
templateUrl: "partials/contact.html",
controller: "contactController",
})
.otherwise({
redirectTo: "/"
});
});
app.controller('ProductController', function($scope, $http){
$http.get('partials/productTable.json').success(function(response){
$scope.datap = response.lists;
});
}).
controller('viewController',function($scope,$routeParams){
$scope.eachproduct = $scope.datap[$routeParams.prodID];
});
And my product.html page code will look like this.
<div ng-controller="viewController">
<ol class="breadcrumb">
<li>Home</li>
<li>Products</li>
<li class="active">{{eachproduct.link}}</li>
</ol>
<div class="col-md-4">
<figure><img ng-src="{{ }}"></figure>
<p>
Read More
</p>
</div>
</div>
Problem is when I navigate to any product page value of {{eachproduct.link}} is not showing.
Any solution will be appriciated.
Use $rootScope instead of $scope
$rootScope
The $rootScope is the top-most scope. An app can have only one $rootScope which will be shared among all the components of an app. Hence it acts like a global variable. All other $scopes are children of the $rootScope.
Sample :
controller('viewController',['$scope','$routeParams', '$http','$rootScope',function($scope,$routeParams, $http,$rootScope){
$http.get('partials/productTable.json').success(function(response){
$scope.datap = response.lists;
$rootScope.eachproduct = $scope.datap[$routeParams.prodID];
});
}]);
app.controller('ProductController', function($scope, $http){
$http.get('partials/productTable.json').success(function(response){
$scope.datap = response.lists;
});
}).
controller('viewController',function($scope,$routeParams, $http){
$http.get('partials/productTable.json').success(function(response){
$scope.datap = response.lists;
$scope.eachproduct = $scope.datap[$routeParams.prodID];
});
});
It seems like what you are looking for is an angular provider such as a factory to store the values in, this will allow the values to be pass values around the controllers while using the routes.
Have a look at this example, while it isn't using routes, the principal is the same:
https://jsbin.com/wiwejapiku/edit?html,js,output
For more information on providers have a look here:
https://docs.angularjs.org/guide/providers
Your example would work something like this:
app
.factory('productFactory',function(){
return {
data: {}
};
})
.controller('ProductController', function($scope, $http, productFactory){
$scope.productFactory = productFactory;
$http.get('partials/productTable.json').success(function(response){
$scope.productFactory.data = response.lists;
});
}).
controller('viewController',function($scope,$routeParams, productFactory){
$scope.productFactory = productFactory;
$scope.eachproduct = $scope.productFactory.data[$routeParams.prodID];
});
Note you would also have to change your view to reference 'productFactory.data' respectively.

How to dynamically insert items from a Array on one page

I would like to direct the pages of templateUrl , en route, to the wizard.html page. To filter fixed items to their respective pages , I use: | filterBy: ['href']:'/sound-waves' , for example. How could insert the items dynamically on one page ?
angular.module('tareasApp')
.controller('NatureCtrl', function ($scope, $routeParams, $sce, $location, $anchorScroll) {
$scope.items =[
{
href:'/sound-waves',
img:'waves.jpg',
video:'//www.youtube.com/watch?v=OG2eGVt6v2o',
description:'Those Relaxing Sounds of Waves'
},
{
href:'/nature-relaxing-sound',
img:'ocean.jpg',
video:'//www.youtube.com/watch?v=SWR0GdC7_40',
description:'Nature Sounds Relaxing Ocean Sounds'
}
];
});
Page wizard.html
<div ng-controller="NatureCtrl">
<div ng-repeat="item in items | filterBy: ['href']: ''" >
<img ng-src="images/{{ item.img }}" width="400" height="200" >
<p>{{item.description}}</p>
<iframe width="655" height="400" ng-src="{{ item.video }}" frameborder="0" allowfullscreen></iframe>
</div>
</div>
Route
angular.module('tareasApp')
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/sound-waves', {
templateUrl: 'views/wizard.html',
controller: 'NatureCtrl'
})
.when('/nature-relaxing-sound', {
templateUrl: 'views/wizard.html',
controller: 'NatureCtrl'
})
.otherwise({
redirectTo: '/'
});
});
The goal is to avoid having multiple pages with the same structure.
Edited: The names of the pages are not in sequence so no . I had put to make it easier to understand . ( Had written as: page-one , page-two changed to sound-waves, nature-relaxing-sound )
Edited: Put the ...controller('NatureCtrl', function... involving the items array for better understanding.
You are right that creating a route for each URL is the wrong way to go, which is why $routeProvider supports route params.
You can define your route as follows:
$routeProvider
.when("/:pageName", {
templateUrl: "views/wizard.html",
controller: "NatureCtrl"
});
and pageName will be available as a $routeParam.pageName:
.controller("NatureCtrl", function($scope, $routeParams){
// ... pageName could be: "sound-waves" or "nature-relaxing-sound"
$scope.pageName = $routeParams.pageName;
});
If the items are coming from a service, say ItemsService, you could also use the resolve property to obtain the items and even pre-filter them as they are coming from the service, as an inject-able parameter for your controller. Here's how it could look like:
$routeProvider
.when("/:pageName", {
templateUrl: "views/wizard.html",
resolve: {
item: function(ItemService, $route){
// $routeParams here would not yet have the params for this route
return ItemsService.getItemsForPage($route.current.params.pageName);
}
},
controller: function($scope, item){
$scope.itemForThePage = item;
}
})

Angular JS deep linking will refresh view

I'm going to try my best to explain this problem. I am also new to Angular so bear with me.
I have two routes that use the same template...
ExampleApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/logbook/following', {
templateUrl: 'views/surf.html',
})
.when('/logbook/following/:surf_id', {
templateUrl: 'views/surf.html',
})
}]);
with two controllers
AppControllers.controller('LogbookController', function($scope, $http, $location, $routeParams) {
$scope.surfs = null;
// Get feed
$http.get(RestURL + 'feeds?filter=following' ).success(function(data) {
if(typeof $routeParams.surf_id == "undefined") {
if(data.length > 0) {
$location.path('/logbook/following/' + data[0].id);
$scope.loadSurfDetail(data[0].id);
}
}
$scope.surfs = data;
});
});
AppControllers.controller('SurfController', function($scope, $http, $location, $routeParams) {
$scope.loading = false;
// Load surf
$scope.loadSurfDetail = function(surfID) {
$scope.loading = true;
$scope.selectedSurf = null;
// Get surf
$http.get(RestURL + 'surfs/' + surfID).success(function(data) {
$scope.selectedSurf = data;
$scope.loading = false;
});
};
if($routeParams.surf_id) {
$scope.loadSurfDetail($routeParams.surf_id);
}
});
using this template file:
<div class="row">
<div class="logbook col-md-3" ng-controller="LogbookController">
<h1>Logbook</h1>
<ol class="surfs-feed">
<li data-id="{{feedSurf.id}}" ng-repeat="feedSurf in surfs" class="surf">
<a href="#/logbook/following/{{feedSurf.id}}">
<strong>{{feedSurf.user.first_name}} {{feedSurf.user.last_name}}</strong>
</a>
</li>
</ol>
</div>
<div class="surf col-md-9" ng-controller="SurfController">
<p class="alert alert-info" ng-show="loading">
Loading...
</p>
<div class="surf-detail" ng-show="selectedSurf">
<pre>
{{selectedSurf | json}}
</pre>
</div>
</div>
</div>
My issue is that when I load a deep link URL, ie. /logbook/following/:surf_id it will use the same template as /logbook/following (adove) and that will cause the logbook feed to be regenerated each time you load up a new surf. So each time you load the surf, the logbook "blinks" and regenerates.
I would like to know how people have tackled this problem without refreshing the feed of surfs and just updating the detail panel on the right hand side...
Thanks!
In your app config, inject $locationProvider and set its html5Mode parameter to true. Then, route changes will not cause the page to refresh.
ExampleApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/logbook/following', {
templateUrl: 'views/surf.html',
})
.when('/logbook/following/:surf_id', {
templateUrl: 'views/surf.html',
})
$locationProvider.html5Mode(true);
}]);

Categories

Resources