AngularJS ui-view not receiving scope - javascript

I want to simply show a sidebar with ng-if when isCreating === true. The ng-click event is from a nmNav directive which is bound to the same controller as the state – NotesController.
But it seems that I'm not managing to pass the scope to the ui-view, though, I have stated that the controller is NotesController.
What I mean by this is that isCreating becomes true on the scope outside of ui-view when startCreating() is called.
▶︎ When setting the variables to the $rootScope everything works
What am I doing wrong?
Here's all relevant code...
notesMan-app.js
angular.module('NoteMan', [
'ui.router',
'ngAnimate',
'notes'
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('notes', {
url: '/',
templateUrl: 'app/components/notes/notes.tmpl.html',
controller: 'NotesController',
controllerAs: 'notesCtrl',
})
.state('note', {
url: '/note/:title',
templateUrl: 'app/components/notes/singleNote/notes-singleNote.tmpl.html',
controller: 'NotesController',
controllerAs: 'notesCtrl',
params: {
title: null
}
});
$urlRouterProvider.otherwise('/'); // when no routematch found redirect to /view1
$locationProvider.html5Mode(true);
})
.controller('NotesController', function ($scope, $stateParams, $state, $http) {
var vm = this;
$scope.isEditing = false;
$scope.isCreating = false;
function showCreating() {
return $scope.isCreating && !$scope.isEditing;
}
function startCreating() {
$scope.isCreating = true;
$scope.isEditing = false;
showCreating();
}
//Define methods
$scope.startCreating = startCreating;
//Get notes from an external file
$http.get('./app/API/notes.json').then(function (res) {
vm.notes = res.data;
});
});
menu.js
angular.module('NoteMan')
.directive('nmNav', function() {
return {
replace:true,
restrict: 'E',
templateUrl: 'app/common/menu/menu.tmpl.html',
controller: 'NotesController as notesCtrl',
link: function (scope, elem, attr){
console.log(scope);
}
};
});

I cant figure out call to "startCreating" in your code.
Below are my guess
a-either you have not specified the controller as "NotesController" to the container element where you are calling method "startCreating"
b-Or you have mispelled the name of controller "NotesController"or method "startCreating"
c-Or you have missed prefixing $scope to call to method "startCreating"
please check and confirm

Related

How can I pass a $scope variable as part of component's templateUrl in angularJs 1.5?

I have the following code:
var myModule = angular.module('myModule', []);
myModule.controller('newController', ['$scope', function($scope) {
$scope.id = '1234';
}])
.component('myModalX', {
templateUrl: `./partials/locationY?id=${$scope.id}`,
controller: 'newController',
controllerAs: 'vm'
});
This doesn't work. How can I ensure that I can pass $scope.id as part of the templateUrl?
Update: I figured out how to do it.
I created a service that has a setter method that accepts the scope I need as a parameter, and a getter method that accesses the set variable in the service.
This way I'm able to access the variable in scope using the getter method in the service.
myModule.controller('newController', ['$scope', 'myScopeAcessingService', function($scope, myScopeAcessingService) {
$scope.id = '1234';
myScopeAcessingService.setValue($scope);
}])
.component('myModalX', {
templateUrl: function(myScopeAcessingService) {
const theIdIneed = myScopeAcessingService.getValue();
return `./partials/locationY?id=${theIdIneed}`
},
controller: 'newController',
controllerAs: 'vm'
});

Updating value on view angular

I have a form in angular, that submits to an API, that returns a 201 status code, and the id and token of the object that was created. My idea is to open up a modal, with that token and show it to the user.
The value of $scope.object.token is updated, but I can't update that state in the view. I tried, $scope.$apply() I get an error $digest already in progress when calling $scope.$apply(). I also tried $timeout() but it doesn't update the view.
controller that handles that behavior is:
angular.module('myApp').controller('ObjectCtrl', ['$scope', 'user', 'object', '$routeParams', '$location', '$uibModal',
function ($scope, user, object, $routeParams, $location, $uibModal, displayToken) {
$scope.object = {
user_id: user.currentUser
}
$scope.create_object = function() {
var promise = object.create($scope.object);
promise.then(function(data){
var token = data.data.token;
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: '/app/views/modal_submit_token.html',
controller: 'ObjectCtrl',
resolve: {
displayToken: function () {
$scope.object.token = token;
}
}
});
});
};
}]);
And on my html,
<p><b>{{ object.token }}</b></p>
To pass the parameter you need to use resolve and inject the items in controller
$scope.Edit = function (Id) {
var modalInstance = $modal.open({
templateUrl: '/app/views/admin/addeditphone.html',
controller: 'EditCtrl',
resolve: {
editId: function () {
return Id;
}
}
});
}
Now if you will use like this:
app.controller('EditCtrl', ['$scope', '$location'
, function ($scope, $location, editId)
in this case editId will be undefined. You need to inject it, like this:
app.controller('EditCtrl', ['$scope', '$location', 'editId'
, function ($scope, $location, editId)
Now it will work smooth, I face the same problem many time, once injected, everything start working!
Font: Pass parameter to modal

How do i can run directive function before controller?

I need call directive function ( i need scope ) before controller.
var app = angular.module('docsRestrictDirective', []);
app.controller('Controller', ['$scope', function($scope ) {
$scope.changeDerictive();
}]);
app.directive('ngMyDer', function() {
return {
restrict: 'A',
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
scope.changeDerictive = function() {
console.log("changed");
};
}
}
}
}
});
http://plnkr.co/edit/NWb23rScg8zvPluGBWH5?p=preview
as requested this is the example with ui-router.
first we will define a controller for the base of the app.
<body ng-app="myApp" ng-controller="AppBaseCtrl">
<main role="main">
<overlay-spinner></overlay-spinner>
<invite-success></invite-success>
<div ui-view></div>
</main>
</body>
now in the ui router we will define our base route:
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/desiredRoute');
$stateProvider
.state('desiredRoute', {
url: '/desiredRoute',
templateUrl: 'views/pathToTemplate.html',
controller: 'MyViewCtrl'
})
});
so what will happen? the base controller runs, we can initialize desired scope variables, then we run the directives and then we run our required controller.
so you have the directive which runs before the needed controller.
if we want this to be cleaner with ui-router we can define the routes like this:
in the routes config:
.state('dashboard', {
url: '/dashboard',
templateUrl: 'views/templates/dashboard/dashboard-base.html',
controller: 'DashboardBaseCtrl',
abstract: true
})
.state('dashboard.main', {
url: '/main',
templateUrl: 'views/templates/dashboard/dashboard-main.html',
controller: 'DashboardMainCtrl'
})
then in the view for the dashboard-base:
<div myDirective></div>
<div ui-view></div>
and of course define in the base controller what ever you want and as you can see... base controller runs then directive then our desired controller so directive runs before the controller...
EDIT
I have created a small plunker like you asked... you will see here that with no timeout the directive is called before our main controller does using a base controller my example is the first example in the answer
plunker with answer
Your ng-controller is written before your directive ,so if you want to call directive frist write ng-controller after your directive
like this
<body ng-app="docsRestrictDirective">
<div ></div>
<div ng-my-der></div>
<div ng-controller="Controller"></div>
</body>
Then it will show result according to you
Plunker: http://plnkr.co/edit/0qccTyPADwDaq05KKmao?p=preview
There is a priority between angularjs directives.ng-controller is directive too,try that priority.Maybe it can help you.
Thanks for answers.
I did it this way
var app = angular.module('app', []);
app.controller( "Ctrl",[ "$scope", function ( $scope ) {
$scope.$watch ( "ngExchange", function ( ) {
$scope._ngExchange[0].remove()
$scope._ngExchange[1].after( $scope._ngExchange[0] );
} );
} ] );
app.directive('ngExchange', function(){
return {
restrict: 'A',
controller: function ( $scope, $element, $attrs ) {
if ( $scope._ngExchange === undefined ) {
$scope._ngExchange = [];
}
$scope._ngExchange.push( $element );
}
}
});
http://plnkr.co/edit/fagINqNafPp6vEhawNbl?p=preview

Get parameters from routeProvider in element directive

I have an element directive and I want to know if I can get parameters from routeProvider to render my template and set it up in my controller.
adminDash.directive('hospitals', function() {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
};
});
How can I get any parameters in my element directive?
You can isolate the scope of the directive, like this:
adminDash.directive('hospitals', function() {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
scope: {
paramValue: '&',
paramVariable: '=',
},
};
});
check this to understand better https://thinkster.io/egghead/isolate-scope-am/
There are 2 ways to do it: both involve using $routeParams service that allows you to retrieve current set of route parameters.
Given that you have an url: http://example.com/#/hospitals/foobar and a route /hospitals/:hospital/ configured in your $routeProvider, you can:
1.Inject $routeParams into your directive:
adminDash.directive('hospitals', function($routeParams) {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
link: function(scope, element){
scope.hospital = $routeParams.hospital;
}
};
});
2.Inject $routeParams into AdminHospitalsController
adminDash.controller('AdminHospitalsController', function($scope, $routeParams) {
$scope.hospital = $routeParams.hospital;
}
Both method will result in having hospital=foobar in your directive's scope;

Restangular method being fired twice

I have the following example:
var loadUserWidget;
loadUserWidget = function() {
console.log(Restangular.one());
if (!$scope.i) {
$scope.i = 0;
}
console.log($scope.i);
return $scope.i = $scope.i + 1;
};
loadUserWidget()
and I get the following console.log
Object {id: undefined, route: undefined, getRestangularUrl: function, getRequestedUrl: function, addRestangularMethod: function…}
cache_list_controller.js?body=1:276
0 cache_list_controller.js?body=1:280
Object {id: undefined, route: undefined, getRestangularUrl: function, getRequestedUrl: function, addRestangularMethod: function…}
cache_list_controller.js?body=1:276
1 cache_list_controller.js?body=1:280
You can see that the restangular method is being fired twice and i can't seem to identify why.
Update:
Contorller:
bbControllers.controller('CacheListController', [
'$scope', 'Restangular', '$rootScope', 'Snippet', '$modal', '$templateCache', "$window", 'Widget', '$sce', '$location', function($scope, Restangular, $rootScope, Snippet, $modal, $templateCache, $window, Widget, $sce, $location) {
var loadUserWidget;
loadUserWidget = function() {
console.log(Restangular.one());
if (!$scope.i) {
$scope.i = 0;
}
$scope.i = $scope.i + 1;
return console.log($scope.i);
};
return loadUserWidget();
}
]);
app.js
var bbPlnkr = angular.module('BBPlnkr', ['BB', 'restangular', 'ngRoute', 'xeditable', 'ngSanitize']);
bbPlnkr.config(function ($routeProvider, $locationProvider, RestangularProvider) {
$routeProvider
.when('/edit', {
templateUrl: '../assets/index.html',
controller: 'CacheListController',
reloadOnSearch: false
})
.when('/edit/:id', {
templateUrl: '../assets/index.html',
controller: 'CacheListController'
})
.when('/invitation/:url', {
templateUrl: '../assets/invitation-detail.html',
controller: 'InvitationController'
})
.otherwise({
redirectTo: '/edit'
});
$locationProvider.html5Mode(true);
});
When using both the ng-controller directive in the template and declaring routes using $routeProvider there will be two instances of the controller, and they will both fire a Restangular request.
If you do
connsole.log($scope.$id);
You should be seeing two different values since there are two different controllers.
Don't use ng-controller when you are using $routeProvider.

Categories

Resources