angular 1 - routing and api - angularjs

Trying to write a simple SPA. Using MEAN.
API through node are all working.
Have set up routes in my main controller
// create the module and name it
var boardingApp = angular.module('boardingApp', ['ngRoute']);
boardingApp.config(function($routeProvider) {
$routeProvider
// route for the home page that lists all tenants
.when('/', {
templateUrl : 'js/templates/tenants.html',
controller : 'tenantsController'
})
// route for a specifc tenant
.when('/tenant/:id', {
templateUrl : 'js/templates/tenant.html',
controller : 'tenantController'
})
});
boardingApp.controller('tenantsController', ['$scope','$http','$log', function($scope, $http,$log) {
$http.get(URL + "/api/tenants")
.then(function(response){ $scope.details = response.data; });
}]);
boardingApp.controller('tenantController', ['$scope','$http','$location','$log', function($scope, $http, $location, $log) {
if ( $location.search().hasOwnProperty( 'id' ) ) {
var myid = $location.search()['id'];
console.log(myid)
myURL = URL + "/api/tenants/"+myid
console.log(myURL)
$http.get(myURL)
.then(function(response){ $scope.tenant = response.data; });
console.log($scope.tenant)
}
}]);
boardingApp.controller('readmeController', function($scope, $http) {
$scope.message = "This is the message"
});
the root route work finds calls the API generates a table. All good
then main part of that template is this
<tbody id="tenantsTable">
<tr ng:repeat = "tenant in details | filter : true: tenant.activeTenant ">
<td><a ng-href = "#/tenant.html?id={{tenant._id}}" >View</td>
<td>{{tenant.roomNumber}} </td>
<td>{{tenant.firstName}} </td>
<td>{{tenant.lastName}} </td>
<td>{{tenant.paymentFrequency}} </td>
<td>${{tenant.rentAmount}} </td>
<td> {{tenant.leaseEnd | date: 'dd MMM yyyy'}} </td>
</tr>
</tbody>
I want to click on the "View" link and pull data from DB for each tenant through and API call that just needs the Tenant id - standard stuff.
My controller is not picking up the request and when i click on the link on the Tennants page it just ends up blank.
what am i missing here? the api call s are all good and working fine

You anchor tab is incorrect, it should be in correct pattern like "#/tenant/{{tenant._id}}"
ng-href="#/tenant/{{tenant._id}}"
Additionally you should retrieve a route parameter inside tenantController by using $routeParams.id API instead of $location.search() which would be look for query parameter.

Related

How to route to an api value from ng-repeat?

I have an api that returns a list of values, i want to be able to click the name of the driver in the api to route to driver details but i cant figure out how to do that.
This is how it looks now
Alternative Look
This is how it should look when i click on the name from ng-repeat from api
i am new to angular and its very confusing atm.
this is my controller.
import { app } from '../index';
app.controller("api", function ($scope, $http) {
$scope.Naziv = "Driver Championship Standings - 2013";
$scope.NazivH1 = "Driver Championship";
$scope.TopDrivers = function () {
console.log("i been pressed");
$http.get("https://ergast.com/api/f1/2013/driverStandings.json")
.then(function successCallback(response) {
$scope.drivers = response.data.MRData.StandingsTable.StandingsLists[0].DriverStandings;
console.log("response.data.MRData.StandingsTable.StandingsLists.0.DriverStandings");
console.log(response.data.MRData.StandingsTable.StandingsLists[0].DriverStandings);
}, function errorCallback(response) {
console.log("Unable to perform get request");
});
}
my routes:
app.config(function($routeProvider, $locationProvider) {
$locationProvider.hashPrefix("!");
$routeProvider
.when("/drivers", {
templateUrl: "./src/pageDetails/drivers.html",
})
.when("/teams", {
templateUrl: "./src/pageDetails/teams.html",
})
.when("/races", {
templateUrl: "./src/pageDetails/races.html",
})
.otherwise({
redirect: "./src/pageDetails/default.html",
});
});
this is the how my template looks.
<div ng-controller="api" ng-init="TopDrivers()">
<h1>{{NazivH1}}</h1>
<div id="modifyDiv">{{Naziv}}</div>
<!-- <button ng-click="TopDrivers()">Test Rest</button> -->
<div ng-repeat="x in drivers | orderBy: '+Points'">
<div id="divRow">
<table>
<tr id="tableRow"><td id="td1">Nb: {{x.position}}</td><td id="td2">{{x.Constructors[0].nationality}} {{x.Driver.givenName}} {{x.Driver.familyName}}</td><td id="td3">{{x.Constructors[0].name}}</td> <td id="td4">Points{{x.points}}</td> </tr>
</table>
</div>
</div>
</div>
firstly why do you have ng-repeat on div and not on <tr>? Do you want a separate div for each driver or do you want a separate row? I suggest you use ng-repeat on <tr> and also add a ng-click directive on your <tr> so whenever someone clicks a driver row, function gets executed on your controller and in that function you can route to the driver details like below:-
<tr ng-repeat="x in drivers | orderBy: '+Points'" ng-click="driverDetails(x.DriverId)" id="tableRow">
<td id="td1">Nb: {{x.position}}</td>
<td id="td2">{{x.Constructors[0].nationality}} {{x.Driver.givenName}} {{x.Driver.familyName}}</td>
<td id="td3">{{x.Constructors[0].name}}</td>
<td id="td4">Points{{x.points}}</td>
</tr>
now in your controller write the driverDetails function like below:-
$scope.driverDetails = function (driverId) {
$location.path('/driverDetails').search({ driverId: driverId });
};
in this function you are changing the url and appending the driverId as query string. Now in the routes add another route
.when("/driverDetails", {
templateUrl: "./src/pageDetails/driverdetails.html",
})
so when the driverDetails function is run in the controller, the driverdetails.html is loaded and you have the driverId in the query srting. Now in the driverdetails controller just retrieve the driverId and make call to your api for that specific driver
You need to add a driver details route with an optional parameter (something like /driver-detail/:id in the route definition). Pass it's own controller, a way to fetch the detail data (you might want to keep it in a service) and then add a ng-click event handler for when the user is in the drivers list ng-repeat and you pass the driver id in there.
Something like :
<tr id="tableRow" ng-click="goToDetail(x.id)">...</tr>
And in the controller :
$scope.goToDetail() = function(id) {
$location.path('/driver-detail/' + id)
}
Your route definition could look something like this :
.when('/driver-detail/:id', {
templateUrl: '...',
controller: function($scope, $stateParams) {
$scope.id = $stateParams.id;
...
}
}
But I strongly recommend you to upgrade your stack, even for AngularJS this is an old way to code - they introduced the component API and particularly for routing, the ui-router is a much more powerful alternative to the ngRouter. If you're starting a project, start with Angular CLI (currently Angular 7) and you'll collect a lot more feedback and find more online resources to guide you.

passing data to another page angular js

I am new to Angular js and want to pass the data from a submit to another page.
How can I make this in angularjs?
I can add lists to a single customer, but I can display the data only in the same page.
I want to display the data in another page after the submit.
I have learnd today, how to use the services, but still I can not pass data from a page to another.
Can anyone help me with a example?
Sorry for my bad English and thank you
// ngRoute code
var app = angular.module('appCheck', ['ngRoute', 'angularUtils.directives.dirPagination']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
controller : "customersCTRL",
templateUrl : "/app/customers/customers.html"
})
.when("/customers", {
controller : "customersCTRL",
templateUrl : "/app/customers/customers.html"
})
.when("/lists", {
controller : "listsCTRL",
templateUrl : "/app/lists/lists.html"
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
}]);
// controller code
$scope.getList = function(id) {
listsService.getSingleCustomer(id)
.then(function successCallback(response, data) {
//$scope.clearForm();
$scope.customer = response.data[0].name;
$scope.id_customer = response.data[0].id;
//$scope.getAll();
//console.log(id);
})
}
$scope.createList = function createList() {
listsService.createList()
.then(function successCallback(response, data) {
$('#addLists').modal('hide');
$scope.clearForm();
})
};
// services code
this.createLists = function() {
return $http.post('/lists/add' , {
"name" : $scope.name,
"id_customer" : $scope.id_customer
})
}
<button ng-click="getListExample(x.id)" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#addL"><span class="glyphicon glyphicon-plus" aria-hidden="true"> Add List</span></button>
<h4 class="modal-title">Add Liste for the customer <span contenteditable="false" ng-bind="cust"></span></h4>
<label>Name of the List</label>
<input type="text" ng-model="name">
<button type="button" ng-click="createListExample()" class="btn btn-primary">Create</button>
You shouldn't pass data. Instead, the other page should get the data it needs to show, from the backend, based on the path parameters.
So the path for the list of customers should be /customers. The associated component gets the list of customers from the backend.
Then, to display a single customer, you would go to /customers/:customerId (example: /customers/42). The componenty would get the details of the customer 42 from the backend.
To display the lists of the customer 42, for example after you have added a list to that customer, you would go to /customers/:customerId/lists (example: /customers/42/lists). The component would get the lists of the customer 42 from the backend.

function not executing on different view

I am new to angular JS. I have created a simple page using ngRoute.
In the first view I have a table, and on clicking it redirects to second view.
But I have called two functions using ng-click the changeView functions is running fine. But the second function fails to execute on the second view.
But Its running fine if using on the first view itself.
Heres the code for first view
Angular.php
<div ng-app="myApp" ng-controller="dataCtr">
<table class='table table-striped'>
<thead>
<tr>
<td>Title</td>
<td>Stream</td>
<td>Price</td>
</tr>
</thead>
<tbody>
<tr ng-repeat = "x in names | filter:filtr | filter:search" ng-click=" disp(x.id);changeView()">
<td >{{ x.Title }}</td>
<td>{{ x.Stream }}</td>
<td>{{ x.Price }}</td>
</tr>
</tbody>
</table>
</div>
heres the second View
details.php:
<div ng-app="myApp" ng-controller="dataCtr">
<div class="container">
SELECTED:<input type="textfield" ng-model="stxt">
</div>
</div>
heres the js file:
var app = angular.module("myApp", ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/angular', {
templateUrl: 'angular.php',
controller: 'dataCtr'
})
.when('/details', {
templateUrl: 'details.php',
controller: 'dataCtr'
})
.otherwise({
redirectTo: '/angular'
});
});
app.controller('dataCtr', function($scope ,$http ,$location ,$route ,$routeParams) {
$http({
method: "GET",
url: "json.php"})
.success(function (response) {$scope.names = response;});
$scope.changeView = function()
{
$location.url('/details');
};
$scope.disp = function(id)
{
$scope.stxt = $scope.names[id-1].Title;
};
});
The disp function is working fine on the angular view. But not being routed on the second view. I think the syntax for calling the two views in ng click is correct. OR if there any other method to call the associated table cell value to the second view. Please Help.
After a lots of research i figured it out.I used a factory service
app.factory('Scopes', function ($rootScope) {
var mem = {};
return {
store: function (key, value) {
$rootScope.$emit('scope.stored', key);
mem[key] = value;
},
get: function (key) {
return mem[key];
}
};
});
Added this to JS.
Because The scope gets lost on second Controller ,Services help us retain the scope value and use them in different controllers.Stored the scope from first controller
app.controller('dataCtr', function($scope ,$http ,$location,$rootScope,Scopes) {
Scopes.store('dataCtr', $scope);
//code
});
and loaded in the seconded controller.
app.controller('dataCtr2', function($scope ,$timeout,$rootScope,Scopes){
$scope.stxt = Scopes.get('dataCtr').disp;
});
Second view is not working because you cannot use $scope.$apply() method.
$apply() is used to execute an expression in angular from outside of the angular framework.$scope.$apply() right after you have changed the location Angular know that things have changed.
change following code part ,try again
$location.path('/detail');
$scope.$apply();

Have a expression error in ui-sref

I am working through the ui-router docs. I have a decent feel for what I am trying to do with ui-sref. In the bottom td I am adding ui-sref to the desired href. I made sure to call the state that I want to fire and the brackets are the route Params that I am trying to create.
the problem is though that I am getting Syntax Error: Token '.' is at column {2} of the expression [{3}] starting at [{4}] from the Angular docs.
I made sure to reference some additional info incase I am missing in any part of my code.
<div class="row" >
<div class="panel panel-primary">
<div class="panel-heading">
Customer List
</div>
<div class="panel-body">
Filter: <input type="text" ng-model="customerFilter">
</div>
<table class="table table-striped table-responsive">
<tr>
<th ng-click="ctrl.doSort('name')">Name</th>
<th ng-click="ctrl.doSort('city')">City</th>
<th ng-click="ctrl.doSort('orderTotal')">order total</th>
<th ng-click="ctrl.doSort('joined')">joined</th>
<th> </th>
</tr>
<tr data-ng-repeat = "cust in ctrl.customers |filter: customerFilter| orderBy:ctrl.sortBy:ctrl.reverse">
<td>{{cust.name | uppercase}}</td>
<td>{{cust.city}}</td>
<td>{{cust.orderTotal | currency}}</td>
<td>{{cust.joined |date}}</td>
<td><a ui-sref="orders({ctrl.cust.id})">View Orders</a></td>
</tr>
</table>
</div>
<span>Total customers: {{ctrl.customers.length}}</span>
</div>
Here is the top part of my controller. I am working with controllerAs and trying to get more used to the John Papa style guide
angular
.module('app.customers')
.controller('CustomerController', CustomerController);
function CustomerController($stateParams) {
var vm = this;
// customerId comes from url param
console.log($stateParams);
var customerId = $stateParams.customerId;
vm.orders = null;
I am getting back an empty object for $stateParams
My route file is broken up as specific as I could make it. I created a view object, created a main view and referenced it in the html. I made a resolve object that will take the $stateParams
angular
.module('app.customers')
.config(config);
function config($stateProvider) {
console.log('customers route')
$stateProvider
.state('customers',{
url:'/customers',
views: {
"main#": {
templateUrl: './components/customers/customers.html',
controller: 'CustomerController',
controllerAs: 'ctrl'
}
},
resolve: {
customerId: ['$stateParams', function($stateParams) {
return $stateParams.customerId;
}]
}
})
};
However, I am just going to the templateUrl I created with no data and the url is not getting the id.
Here is my orders controller
(function() {
'use strict';
angular
.module('app.orders')
.controller('OrdersController', OrdersController);
function OrdersController($stateParams) {
console.log('in orders');
var vm = this;
vm.title = "Customer Orders";
}
}());
This is the route that I set up for orders. I made sure to reference :Id each contact id.
(function() {
'use strict';
angular
.module('app.orders')
.config(config);
function config($stateProvider) {
$stateProvider
.state('orders',{
url:'/orders:customerId',
templateUrl: './components/orders/orders.html',
controller: 'OrdersController',
controllerAs: 'ctrl'
})
// $locationProvider.html5Mode(false);
};
})();
Firstly, state should define the parameter. It could be part of url or params : {} (or both), but at least some...
// params
.state('customers',{
url:'/customers',
params: { customerId : null }
...
// url
.state('customers',{
url:'/customers/:customerId',
...
// url & params
.state('customers',{
url:'/customers/:customerId',
params: { customerId : 1 } // default value
...
Having this, we can create ui-sref like this:
// instead of this
<td><a ui-sref="orders({ctrl.cust.id})">View Orders</a></td>
// we need object with name customerId and its value
<td><a ui-sref="orders({customerId: ctrl.cust.id})">View Orders</a></td>
For more details check this Q & A:
How to pass parameters using ui-sref in ui-router to controller
I think one part of the issue is that ctrl.cust.id should just be cust.id

finish a controller treatment before execute another

i have 2 controller loaded in one page : one loaded by $routeProvider,
application.js
.when('/service/:serviceId/:serviceName/',
{
templateUrl : 'view/service/service.html',
controller : 'ServiceController'
})
the other loaded in the view
service.html
<div align="left">
<table class="table-flag">
<tr ng-controller="LanguageController">
<td ng-repeat="language in listLanguage"
width="50">
<input type="image" ng-src="img/flags/{{language.code}}.jpg"width="30" height="20"></input> </a>
</td>
</tr>
</table>
<div>
<br />
<ul>
<table class="table table-hover">
<tbody>
<tr
ng-repeat="detail in service.infoList">
<td><span ng-bind-html-unsafe="detail.label"></span></td>
</tr>
</tbody>
</table>
</ul>
</div>
</div>
I retrieve some datas from a server using rest
ServiceController
Info.controller('ServiceController', function ServiceController(
$scope, $http, $routeParams, manageDatas) {
$scope.serviceId = $routeParams.serviceId;
$scope.serviceName = $routeParams.serviceName ;
var paramsService = {
serviceId : $scope.serviceId,
serviceName : $scope.serviceName
};
$scope.loading = true;
var response = $http({
url : 'rest/service',
params : paramsService,
method : 'GET'
});
response.success(function(service) {
$scope.service = service;
$scope.loading = false;
manageDatas.setArrayData($scope.service.languageList); // service which allow to pass an array in LanguageController
});
});
LanguageController
LanguageController.controller('LanguageController', function ServiceByLanguageController(
$scope, $http, $routeParams, $timeout , manageDatas , $route) {
$scope.listLanguage = manageDatas.getDatas(); // retrieve the array passed in ServiceController by a service
// always null
});
The problem is the $http.success method in ServiceController is always executed AFTER LanguageController(verified by breakpoints) so the array $scope.listLanguage is always empty because i don t pass datas....
How can i make the languageController be executed after all the treatments in serviceController finish ?
Thank you very much
Alternatively, you can broadcast event in response.success(function(service) {...}, say, using $rootScope, and let LanguageController listen to this event and then do assignment $scope.listLanguage = ...
Just after a brief look, I would say that part or all of your ServicesController logic should be in a service and not a controller. You seem to have such a service in manageDatas. Just put all the code that actually loads and writes data to the service inside the service.

Resources