AngularJS works once then no longer renders - javascript

So I am trying to list out some data from an API call, which is JSON. I am new to Angular and JavaScript and I think the whole Async thing is messing with my logic. Sometimes when I refresh the page, it works perfectly, all the data I expect to be there is, but then the next time I refresh its gone. This seems to happen when I change something in the controller.
var app = angular.module("hasRead", ['hasRead.controllers', 'hasRead.directives', 'hasRead.services', 'hasRead.filters','ngRoute']);
app.config(["$routeProvider", function ($routeProvider) {
$routeProvider
.when("/books/:shelf", {controller: "BooksCtrl", templateUrl: "partials/books_list.html"})
.when("/recomend", {controller: "RecomendCtrl", templateUrl: "partials/recomend.html"})
.otherwise({redirectTo: "/books/read"})
}]);
controller.js
var ctrls = angular.module('hasRead.controllers', []);
ctrls.controller('AppCtrl', function ($scope) {
});
ctrls.controller('BooksCtrl', function ($scope, $book, $routeParams) {
$scope.books;
var shelf = $routeParams.list;
$book.getBooks(shelf).then( function(data) {
$scope.books = data.query.results.body.goodreadsresponse.reviews;
console.log($scope.books);
$scope.$apply;
});
});
ctrls.controller('RecomendCtrl', function ($scope) {
$scope.test = "testing";
});
HTML
<div>
<book ng-repeat="review in books.review" review-data="review"></book>
</div>
Its a fair bit of code so here is a plunkr:
https://plnkr.co/edit/l3A6QF?p=info

I didn't have the parentheses in $scope.$apply(); in the controller.

Related

Defining angular controllers and component

I'm trying to call a function from within one angular component's controller to another component's controller. I found this answer, but the controllers are defined differently than what is shown in the tutorials I followed, so I'm confused as to how I'm supposed to reference the components and templates.
Here is how I currently define one of my controllers based on the official angular tutorial
angular.
module('moduleName').
component('firstComponent', {
templateUrl: 'url/to/template',
controller: function FirstController($scope) {
//I want to call a function in SecondController here
}
});
//in another component file
angular.
module('moduleName').
component('secondComponent', {
templateUrl: 'url/to/template',
controller: function SecondController($scope) {
//function here which will be called
}
});
Say I re-structure them like in the example I linked above...
var app= angular.module("myApp",[]);
app.controller('One', ['$scope', '$rootScope'
function($scope) {
$rootScope.$on("CallParentMethod", function(){
$scope.parentmethod();
});
$scope.parentmethod = function() {
// task
}
}
]);
//in another file
var app= angular.module("myApp",[]);
app.controller('two', ['$scope', '$rootScope'
function($scope) {
$scope.childmethod = function() {
$rootScope.$emit("CallParentMethod", {});
}
}
]);
How am I supposed to reference each controller's component which they belong to, and their respective templates? I tried to write them like in the example I linked above, but nothing happened. I didn't get any errors, but literally nothing happened. Nothing was displayed on the page. It tried to write to the console, but nothing appeared.
Your second block of code has the right concept, but both controllers need to be instantiated for it to work.
Here's a working JSFiddle. https://jsfiddle.net/reid_horton/rctx6o1g/
When you click the button, the text Hello from callerComponent! appears below it.
HTML
<div ng-app="myApp">
<caller-component></caller-component>
<callee-component><</callee-component>
</div>
JS
var app = angular.module("myApp", []);
app.component("callerComponent", {
template: "<button ng-click='externalCall()'>Click Me!</button>",
controller: function ($scope, $rootScope) {
$scope.externalCall = function () {
$rootScope.$emit("setText");
}
}
});
app.component("calleeComponent", {
template: "<p>{{ myText }}</p>",
controller: function ($scope, $rootScope) {
$rootScope.$on("setText", function () {
$scope.myText = "Hello from callerComponent!"
});
}
});

Dynamically changing routes using AngularJS

I have bunch of JSON models in my project and I need to show different models depends on user's actions.
Here is Angular router code:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}).when('/doc/:section, {
templateUrl: 'views/doc.html',
controller: 'DocCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
And here is DocCtrl.js file:
app.controller('DocCtrl', ['$scope', '$http', 'JSONModelsService',
function ($scope, $http, JSONModelsService) {
var formData = {};
$scope.group = {};
$scope.sections = [];
JSONModelsService.get([section])
.then(function (response) {
console.log(response);
$scope.group = response.data.groups[0];
$scope.sections = $scope.group.sections;
});
}]);
I basically need to make section dynamic so I can show different models in my views. However, I'm confused how I can do it. I just have a folder called JSONModels with multiple json files.
If I understand your question correctly, you are aiming at replacing the [section] part of your code with an actual section identifier?
When a user visits your /doc/:section route, e.g. /doc/my-doc you can access the :section part by injecting the $routeParams service into your controller.
app.controller('DocCtrl', ['$scope', '$http', '$routeParams', 'JSONModelsService',
function ($scope, $http, $routeParams, JSONModelsService) {
...
Using the $routeParams service, you have access to your route parameters. So you can simple access the :section parameter, by reading it off $routeParams.section.
A full example (of what I think you're trying to achieve):
app.controller('DocCtrl', ['$scope', '$http', '$routeParams', 'JSONModelsService',
function ($scope, $http, $routeParams, JSONModelsService) {
var formData = {};
$scope.group = {};
$scope.sections = [];
JSONModelsService.get([$routeParams.section])
.then(function (response) {
console.log(response);
$scope.group = response.data.groups[0];
$scope.sections = $scope.group.sections;
});
}]);
If you would like to know more, take a look at step 7 of the angular tutorial: https://docs.angularjs.org/tutorial/step_07

unable to pass data between the views in angularjs through routing

In my angularjs app, I am trying to pass the data from one cshtml view to another view through routing but in details.cshtml, I don't see the data coming into it though I can see the change in URL
Index.cshtml (View1)
{{addprodtocart}}
Controller.js
app.controller('CartController', function ($scope) {
$scope.SendToCartPage = function(cartprd)
{
var len = cartprd.length - 1;
$scope.cid = cartprd[len];
}
});
Details.cshtml ( I don't see the data coming into the span below)
<div ng-controller="CartController">
<span ng-model="cid">{{cid}}</span>
</div>
Myrouting
var app = angular.module("productmodule", ["ngRoute"]);
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/Details/:cid', {
templateUrl: '/Product/Details',
controller: 'CartController'
});
}]);
I created a plunker for this. I am unable to send the data from page1 to page2
http://plnkr.co/edit/micM7vlslznEIZXP293Y?p=preview
Your problem is your controller is instantiated again while clicking on href and the scope is getting recreated & $scope.cid is set to undefined.
You could achieve the same by using $routeParams which will give the access to what url contains
In your case it would be $routeParams.cid
Code
app.controller('CartController', function ($scope, $routeParams) {
$scope.SendToCartPage = function(cartprd)
{
var len = cartprd.length - 1;
//$scope.cid = cartprd[len];
}
$scope.cid = $routeParams.cid;
});
Update
You should use $routeParams service to get data from url
Code
var app = angular.module('plunker', ['ngRoute']);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/Details/:cid', {
templateUrl: 'page2.html',
controller: 'CartController'
}).when('/', {
templateUrl: 'page1.html',
controller: 'CartController'
});
}
]);
app.controller('CartController', function($scope, $routeParams) {
$scope.myvar = $routeParams.cid; //this will asign value if `$routeParams` has value
console.log($scope.myvar);
$scope.Add = function(c) {
$scope.myvar = c;
}
});
Working Plunkr

AngularJS - Passing ID from a page and populate in other page

I am new to AngularJS. In my project I have a search screen when search I will get the search result in the ngGrid.
On click of any row in the grid, it should populate the details of that row in other page. Basically, I need to pass the ID of the selected record to the other page. I don't know how to handle this in AngularJS (I am using AngularJS HotTowel template) and Breeze for data access logic.
Appreciate if you could provide me link or any where it is implemented which I could refer.
You can create service and share values for instance
var myApp = angular.module('myApp', []);
myApp.factory('ShareData', function() {
var shared;
return {
setValue: function(val){
shared = val;
},
getValue: function(){
return shared;
}
});
function FirstCtrl($scope, ShareData){
ShareData.setValue(1);
}
function SecondCtrl($scope, ShareData){
$scope.data = ShareData.getValue();
}
You need $routeParams for this.
Below is an example of the routing configuration:
var app = angular.module("app", ["ngRoute"])
.config(["$routeProvider", function ($routeProvider) {
$routeProvider
.when("/", {
controller: "HomeController",
templateUrl: "/home/main",
})
.when("/products/:category", {
controller: "ProductController",
templateUrl: "/product/index"
})
.otherwise({
redirectTo: "/"
});
}]);
Product Controller
angular.module("app")
.controller("ProductController",["$scope","$routeParams", function($scope,$routeParams){
$scope.category = $routeParams.category;
alert($scope.category);
}]);
'Main' View
<a ng-href="#/products/ladies">Ladies</a>
check this URL for more info:
https://docs.angularjs.org/api/ngRoute/service/$routeParams

Multiple Controllers for one view angularjs

I would like to know if it is possible to use multiple controllers for a single url view using angluarjs, I have not been able to find much documentation on this. I would like to use a controller on all pages to switch the page header title, but some pages already contain a controller
app.js
subscriptionApp.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/billinginfo',{templateUrl:'views/billing-info.html', controller:'billingInfoController'}).
when('/orderreview',{templateUrl:'views/order-review.html', controller:'billingInfoController'}).
when('/subscribed',{templateUrl:'views/subscribed.html', controller:'subscribedTitle'}).
//EXAMPLE: HOW COULD I ADD TWO CONTROLLERS TO SAME PAGE??? THIS DOES NOT WORK
when('/subscribe',{templateUrl:'views/subscribe.html', controller:'subscriptionController', 'testControllerTitle'}).
when('/unsubscribed',{templateUrl:'views/cancelconfirm.html', controller:'unsubscribedTitle'}).
when('/redirectBack',{templateUrl:'views/redirect-to-app.html'}).
when('/redirectHandler',{templateUrl:'views/redirect-handler.html',controller:'redirectController'}).
when('/error',{templateUrl:'views/error.html', controller:'messageController'}).
otherwise({redirectTo:'/subscribe'});
}]);
EDIT
I am trying to add a title controller to each page view:
function testControllerTitle($rootScope, $scope, $http) { $rootScope.header = "Success!"; }
If I add this controllers to the pages that don't already have a controller it works, if there is another controller in place I can't make this work.
<h1 ng-bind="header"></h1>
Yes, controllers and templates are independent, check this http://jsbin.com/wijokuca/1/
var app = angular.module("App", ['ngRoute']);
app.config( function ( $routeProvider ) {
$routeProvider
.when('/a', {templateUrl: 'this.html', controller: "aCtrl"})
.when('/b', {templateUrl: 'this.html', controller: "bCtrl"})
.when('/c', {templateUrl: 'that.html', controller: "bCtrl"})
.otherwise({redirectTo: '/a'});
});
app.controller('aCtrl', function ($scope) {
$scope.all = [1,2,3];
});
app.controller('bCtrl', function ($scope) {
$scope.all = [4,5,6];
});

Categories

Resources