How to call different view when submitting form? - javascript

I have index.html file which have these following below codes. I want to show result to other view searchResult.html when submitting the form. I retrieve the form data in homeCtrl but i can't do when submitting the form show the retrieved data to searchResult.html page. Please help me.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
//head code...
</head>
<body ng-controller="homeCtrl">
<form ng-submit="doSearch()">
<input type="search" placeholder="From" ng-model="search.from">
<input type="search" placeholder="Destination" ng-model="search.to">
<button type="submit">Search</button>
</form>
<div ng-view></div>
</body>
</html>
var app = angular.module('myApp', [])
app.controller('homeCtrl', function($scope, $location) {
$scope.doSearch = function() {
$scope.search={};
$scope.search=$scope.search;
//retrieved data here
}
});

You can get the data in homeCtrl and store it in rootscope or localstorage then redirect page to search page and retrieve data from rootscope or localstorage to searchCtrl scope.

It may be tempting to pass data around through the $rootScope, but this is problematic. To start, your data is now bound to the root scope, and can’t be moved off into isolation. Not only is this harder to test, but it can’t be used through multiple applications if need be.
take out your Searching logic in Separate Service.
use ui-router for URL routing.
Following links will be helpful!
navigation with routing -part1
navigation with routing -part2

Related

Image is not displaying until we refresh the page

In my application, when we logged in I am passing an Http get request for an image. The image is being loaded successfully but it is not displayed until I refresh the page.
I want it to be displayed when I logged in by using angular in my application.
<img ng-src="{{ProfileImage}}" />
This is the HTTP call:
$http.get('URLpath')
.then(function(response){
$scope.ProfileImage=response.data;
}
The image is getting loaded from the source but it is not displayed immediatley when i log in.
It is displayed after refreshing the page.
var app = angular.module('myApp', []);
app.controller('DemoCtrl', function($scope, $http) {
$scope.myObj = {
"image":"https://www.w3schools.com/css/trolltunga.jpg",
};
});
<!DOCTYPE html>
<html>
<body>
<div ng-app="myApp" ng-controller="DemoCtrl">
<img src="{{myObj.image}}" width="100" height="100">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</body>
</html>
You should either wrap your image to ng-if so it should appear after the data is loaded or assign some valid data to $scope.ProfileImage before response comes. Otherwise, your ng-src is neglected.
thanks for the response guys.
This issue is fixed by storing the image to window local storage and then accessing it using angular {{ProfileImage}}.

Angularjs: How To Call Controller Function After Routing

I'm learning angularjs and there is one aspect of it that I'm struggling to understand.
My desired/expected behavior of the code below is:
User clicks the Paris link (anchor tag)
The routeProvider intercepts the request, loads the paris.html page into the ng-view.
The 'getCity' function in the controller gets the data and sets the scope variables, which are displayed in the london.html expressions.
However, I can't figure out how to config angularjs to use the 'getCity' function when the html page is loaded into the ng-view. The closest I can get is calling the 'getCity' function from within the CityController itself, bit this seems to have the undesired effect of calling the function when the whole app (index.html) is loaded instead of only when the link is clicked. The controller will have a number of different functions.
I also know you can use ng-click to call a controller's function, but I'm unsure how this would work with loading a html page into an ng-view through the route provider.
Any help would be appreciated. Please see code below from a small app built for learning purposes:
index.html
<!DOCTYPE html>
<html ng-app="mainApp">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-route.js"></script>
</head>
<body>
<ol>
<li>Paris</li>
</ol>
<div class="content-wrapper" ng-controller="CityController">
<div ng-view></div>
</div>
<script src="resources/js/app.js"></script>
<script src="resources/js/CityController.js"></script>
</body>
</html>
app.js
var app = angular.module("mainApp", [ 'ngRoute' ]);
app.config([ '$routeProvider', function($routeProvider) {
$routeProvider.
when('/cities/paris', {
templateUrl : 'resources/paris.html',
controller : 'CityController'
}).
otherwise({
redirectTo : ''
});
} ]);
CityController.js
app.controller('CityController', function($scope, $http) {
$scope.getCity = function() {
$http.get('city')
.success(function(response) {
$scope.name = response.name;
$scope.country = response.country;
}).error(function() {
//Output error to console
});
};
//$scope.getCity();
});
I don't want to call getCity here because it means the http get request to
the 'city' endpoint is called when index.html is loaded
paris.html
This is Paris.
<br><br><br>
Name: {{name}}<br>
Country: {{country}}
<br><br><br>
I think what you are looking for is the router resolve option.
A resolve contains one or more promises that must resolve successfully before the route will change. This means you can wait for data to become available before showing a view, and simplify the initialization of the model inside a controller because the initial data is given to the controller instead of the controller needing to go out and fetch the data.
Check the explanation and usage here
You can call getCity() from paris.html using ,ng-init=getCity() ,ng-init will call your function as soon as paris.html is loaded into your ng-view .
For Eg.
This is Paris.
<br><br><br>
<div ng-init=getCity() >
Name: {{name}}<br>
Country: {{country}}
</div>
<br><br><br>

Another ng-click() not working as expected

I am sure this is something fundamental, but I can not find it. I am trying to send data back to the controller. I believe the ng-click event is not firing. This was my attempt to debug the issue. I believe I have stripped it down to the bare essentials for a simple alert..
here is the controller and the partial view
angular.module('FieldApp', [])
.controller('FieldCtrl', function($scope, $http) {
$scope.createField = function($scope, $http) {
alert("Create Field");
}
})
<script src="./bower_components/angular/angular.js"></script>
<script src="./bower_components/angular-route/angular-route.js"></script>
<div class="container" ng-app="FieldApp" ng-controller="FieldCtrl">
<button type="button" class="btn btn-primary btn-lg btn-block" ng-click="createField()">Add Field</button>
</div>
<script src="./js/field.js" charset="utf-8">
cheers
The dependencies parameters in the function are unnecessary. Just declare the function like this:
$scope.createField = function() { ... }
And you need to reference to the $window dependency to show the alert:
$window.alert("Create Field");
Don't forget the include $window in the dependencies list of your controller (.controller('FieldCtrl', function($scope, $http, $window) {).
But it's better to just do console.log("Create Field"); instead.
The window reference is not necessary. This is how I would write your code. I don't know exactly what's going on in your code, but it is usually good practice to set a variable for the module.
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script>
var app = angular.module('FieldApp', []);
app.controller('FieldCtrl', ['$scope', function($scope) {
$scope.createField = function() {
alert("Create Field");
};
}]);
</script>
</head>
<body>
<div ng-app="FieldApp">
<div ng-controller="FieldCtrl">
<button ng-click="createField()">Add field</button>
</div>
</div>
</body>
</html>
This code segment worked on my machine.
I don't see any problem with your code. I've created a jsFiddle from it:
https://jsfiddle.net/gcsgggcw/
I've just stripped the javascript links from your html:
<div class="container" ng-app="FieldApp" ng-controller="FieldCtrl">
<button type="button" ng-click="createField()">Add Field</button>
</div>
The cause must be something else; did you checked if all the javascript files are loaded properly in the browser?
The solution was a case of not formatting a variable name correctly. I had myApp in one file and MyApp in another file. It has been many years since I used a text editor instead of Visual Studio.

angularJS $http.get communicating with API

I am new to AngularJS and I am trying to understand it by studying sample codes.
Here I have one about $http.get, from the following link:
http://www.w3schools.com/angular/tryit.asp?filename=try_ng_customers_json
I just replaced url with one of my own but it did not work, and I am really confused, please help, thanks!
=========================
second edit: thanks to the answers, double ng-app is a mistake, but it is not the main reason for this problem. I think it has something to do with cross-site blocking, but I have turn it off on my API (I use codeigniter REST API and I set $config['csrf_protection'] = FALSE; ), I am not sure how to configure it.
<!DOCTYPE html>
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="customersCtrl">
<ul>
{{names}}
</ul>
</div>
<div ng-controller="myCtrl">
<ul>
{{names}}
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/website/Customers_JSON.php")
.success(function (response) {$scope.names = response;});
});
app.controller('myCtrl', function($scope, $http) {
$http.get("https://manage.pineconetassel.com/index.php/api/v1/colors2.php")
.success(function (response) {$scope.names = response;});
});
</script>
</body>
</html>
The problem is that you have two "myApp" declarations.
From AngularJS documentation:
Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application.
So, you should move the ng-app="myApp" to the body element.
However, once you've done that you probably still won't see any result because you are cross-site scripting and browsers will (by default) block the second request.
Two ng-app directive on single page will execute the first one, 2nd one will get ignored.
Remove ng-app="myApp" from both div of your html and use angular.bootstrap to bootstrap angular app on html page using below code.
Code
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});

angular-ui view nested in a directive does not load view content

if I nest ui-view inside a directive with transclude=true, the view content does not load. It works fine without the intervening directive.
so with a page containing:
<body>
<div ng-controller="MainController">
<div ui-view="sampleView"></div>
</div>
</body>
the sampleView content appears.
But if i put
<body>
<div ng-controller="MainController">
<div sample-directive>
<div ui-view="sampleView"></div>
</div>
</div>
</body>
then the view content doesn't appear.
I have created a simple html page to demonstrate the problem, see below.
As far as I can see, the angular compiling process does correctly call updateView in the ui-view directive in angular-ui, and that does build the view content and insert it in the dom under the sample-directive node, but that doesn't seem to be the actual visible sample-directive node, but a clone of it. i'm guessing it has to do with the order of compilation and therefore I need to do something clever in the directive, but i can't find anything in the angular api help that covers this point.
i've tried adding a post-link function and calling $transclude from there but it makes no difference.
can anyone advise what i need to add to the directive so this will work.
thanks
UPDATE
New info from further investigation:
It seems the cause is this (not at this point a solution, but I can see why it happens).
In angular's function applyDirectivesToNode (angular.js line 5919), if a directive specifies transclude=true, then the original directive node is cloned to make the template node. ie the template is not the original node that's visible in the dom. Now, when the compile function of ui-view in angular-ui-router.js line 2204 is called, it grabs a copy of the parent of the ui-view node, storing it in parentEl. But, and here's where the problem occurs - this parent is the parent in the dom of the ui-view node. what it's most certainly not is the instance of the parent that actually ends up in the dom after linking. Later when the ui-view updates for the initial route change, it builds the view content and inserts it under parentEl (angular-ui-router.js line 2273), but as we saw earlier this isn't in the visible dom after linking. it's the source html node and not the clone created by compiling and linking the directive in which the ui-view is nested.
I think this may be a bug in ui-view.
There may be a way to add a workaround to the directive, to get the post-link view instance and put it into the directive. If I figure it out I'll add an answer.
html to demonstrate the issue as follows:
<!DOCTYPE html>
<html lang="en" ng-app="viewInDirectiveApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>View inside a directive</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
<script src="modules/angular-ui-router.js"></script>
<script>
var viewInDirectiveApp = angular.module('viewInDirectiveApp', ['ui.router']);
viewInDirectiveApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('sampleState', {
url: '/sampleState',
views: {
sampleView: {
template: 'This is the view content',
controller: function ($scope) {
}
}
}
});
$urlRouterProvider.otherwise("/sampleState");
})
.controller('MainController', ['$scope',
function ($scope) {
}])
.directive('sampleDirective', function () {
return {
template: 'Start directive content <div ng-transclude></div> End directive content',
transclude: true
};
});
</script>
</head>
<body>
<div ng-controller="MainController">
Before sampleDirective
<div sample-directive>
Before sampleView
<div ui-view="sampleView"></div>
After sampleView
</div>
After sampleDirective
</div>
</body>
</html>
Confirmed bug in ui-router 0.2.8: https://github.com/angular-ui/ui-router/issues/774
Fixed in 0.2.10: https://github.com/angular-ui/ui-router/pull/858
Plunkers are much appreciated: http://plnkr.co/edit/TZ8hvkSbCIa0dTj0NkcG?p=preview - Seems to work in Angular-routing: http://dotjem.github.io/angular-routing/

Categories

Resources