Can't call a function when using $routeProvider - html

I have an index page with <div ng-view></div> block in it. Here using $routeProvider various templates are inserted.
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'templates/home.html',
controller: 'mainController',
css: 'css/style.css'
})
// route for the report page
.when('/report', {
templateUrl: 'templates/report.html',
controller: 'reportController',
css:['css/results.css','css/chart.css']
})
// route for the admin panel
.when('/adminpanel', {
templateUrl: 'templates/admin.html',
controller: 'adminController'
})
In one of the templates I have a form that upon submission calls a function using Angular ng-click="processPdf()".
<div class="remodal" data-remodal-id="download" role="dialog">
<button data-remodal-action="close" class="remodal-close"></button>
<h4 class="factor-title">Download Your PDF</h4>
<div class="window-message">
<form class="remodal-form" name="download-pdf" id="download-pdf">
<input type="email" placeholder="Enter your email" name="download-email" id="email" required>
<button ng-click="processPdf()" type="submit" class="download"><i class="fa fa-file-pdf-o fa-3x"></i> <span>Download PDF</span></button>
</form>
<button class="back-fixit" data-remodal-target="fixit"><i class="fa fa-long-arrow-left"></i> Back</button>
</div>
</div>
The problem is that once I call it, it provides invalid path: instead of saying /report/?email=zzz.com, it makes ?email=zzz.com/report even though the function is used on the report template. I have no clue what to do and any help will be appreciated.

Related

How to display a calculation result on a New view/page in Angular?

I am new in Angular. I'm trying create my first simple Angular calculator app, everything fine. Now I want to do this : When I perform a calculation, the result of that calculation will be displayed in another view/page. Can you show me some ways or keywords for this ?
My app:
Code:
calculator.component.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="card">
<div class="card-header">CALCULATOR</div>
<div class="card-body">
<div class="form-group value">
<div class="form-group row">
<label class="col-md-2 col-form-label">Value 1:</label>
<div class="col-md-10 input-1">
<input [(ngModel)]='number1' class="form-control inp" type="number" name="num1">
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label">Value 2:</label>
<div class="col-md-10 input-2">
<input [(ngModel)]='number2' class="form-control inp" type="number" name="num2">
</div>
</div>
</div>
<div class="buttons">
<br>
<button class="butt" (click)='sum()'> + </button>
<button class="butt" (click)='diff()'> - </button>
<button class="butt" (click)='mult()'> x </button>
<button class="butt" (click)='divi()'> / </button>
<br><br><br>
</div>
<div class="result">
<h3 class="">Result: {{result}}</h3>
</div>
</div>
</div>
</body>
</html>
calculator.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-calculator',
templateUrl: './calculator.component.html',
styleUrls: ['./calculator.component.css']
})
export class CalculatorComponent implements OnInit {
public number1: number;
public number2: number;
public result: number;
constructor() {
}
sum() {
this.result = this.number1 + this.number2;
}
diff() {
this.result = this.number1 - this.number2;
}
mult() {
this.result = this.number1 * this.number2;
}
divi() {
this.result = this.number1 / this.number2;
}
ngOnInit(): void {
}
}
In CalculatorComponent, call this function after each calculation in order to set the result of calculation:
setTotal(){
localStorage.setItem('total', this.result);
}
Now trigger new page to be open..
Then, go to new page's ts file, and retrieve the result from localStorage:
this.total = localStorage.getItem('total');
Now in html file belonging to new page, display the result:
{{ totalĀ }}
use angular routing for display data one page to another page
this.router.navigate(['your page name'], { state: value })
state: value means you have to pass value of your result
The right way to do that is creating a service component, that will be used to set and read data (this is the order you need in your example, but could be any). Please, note you should know how to subscribe to this service component, so i recommend you to read about subscribers and observables before.
Using angular routes or localStorage is not secure, so i wouldn't do that. The major rason is this could be easily modified by end-users

how to use/implement input tags and custom jsx tag for syntax highlighting using Highlight.JS?

I was just searching around how to highlight code just like Text editors on website and I found some libraries and I liked highlight.js and started to play around with it.
But to my sense it worked well except for the <input/>tags and custom react component tags doesn't get rendered well.
I followed the documentation and implement the code in following manner:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/night-owl.min.css">
<div class="code-container" style="margin: auto; width: 50%;">
<pre><code data-language="html">
import React, { Component } from 'react'
import './reg-style/Credentail.css'
import 'react-phone-number-input/style.css'
import PhoneInput from 'react-phone-number-input'
export class Credential extends Component {
continue = e => {
e.preventDefault();
this.props.nextStep();
};
back = e => {
e.preventDefault();
this.props.prevStep();
};
render() {
const { values, handleChange } = this.props;
return (
<pre>
<code data-language="html">
<div>
<Helmet>
<body className="form-bg-col"></body>
</Helmet>
<div className="login">
<div className="reg-container">
<button onClick={this.back} className="col-form-prev"><i class="fa fa-chevron-left"></i></button>
<div className="user-detail email">
Email:
<input onChange={handleChange('Email')} defaultValue={values.Email} type="email" placeholder="Enter your Email"/>
</div>
<div className="user-detail ">
Phone:
<PhoneInput
onChange={handleChange('Phone')} defaultValue={values.Phone}
displayInitialValueAsLocalNumber
placeholder="Enter phone number"
defaultCountry="IN"
/>
</div>
<div className="user-detail username">
Username:
<code><input onChange={handleChange('Username')} defaultValue={values.Username} type="text" placeholder="Select your unique Username" /></code>
</div>
<div className="user-detail password">
Password:
<input onChange={handleChange('Password')} defaultValue={values.Password} type="password" placeholder="Choose your Password" />
</div>
<button onClick={this.continue} className="col-form-next"><i class="fa fa-chevron-right"></i></button>
</div>
</div>
</div>
</code>
</pre>
)
}
}
export default Credential
</code></pre>
</div>
and result was as following:
What should i do to rectify these issues?
Thanks...
All the HTML inside your pre/code block HTML needs to be properly escaped to avoid code injection.... This is just how HTML works.
Bad (this is actual HTML and will be rendered by the browser):
<pre><code>
<strong>Hey I'm HTML</strong>
</code></pre>
Good (now it's just text [when rendered]):
<pre><code>
<strong>Hey I'm HTML</strong>
</code></pre>
[Disclaim: I'm the current Highlight.js maintainer.]

Why does using *ngIf = "authService.getUser()" in my top level app component html break my login component?

I am new to Angular so please bear with my naivety. I created a login component, which I use to prevent access to router navigation links in the main app-component html until the user logs in. The login component itself is another routed page, and I wanted to instead add the login component to my mainpage, and hide the routing navigation links until the user logs in.
To hide the user navigation links in the app-component html I tried using
*ngIf="authService.getUser()".
*ngIf="authService.getUser()" hides the navigation components until the user is logged in as expected, but it unexpectedly also didn't render the entirety of the login component (the user and password fields and submit button), except the first text which simply says "LOGIN". So the user has no way to login.
this is app.component.html:
<app-login>
</app-login>
<div class="page-header" >
<div class="container">
<div *ngIf="authService.getUser()" class="navLinks">
<a [routerLink]="['/home']"> Home</a>
<a [routerLink]="['/about']"> About App</a>
<a [routerLink]="['/login']">Login</a>
<a [routerLink]="['/protected']">Protected</a>
</div>
</div>
</div>
<div id="content">
<div class="container">
<router-outlet></router-outlet>
</div>
</div>
and these are my login component files
login.component.ts:
import { Component } from '#angular/core';
import { AuthService } from '../auth.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
message: string;
constructor(public authService: AuthService) {
this.message = '';
}
login(username: string, password: string): boolean {
this.message = '';
if (!this.authService.login(username, password)) {
this.message = 'Incorrect credentials.';
setTimeout(function() {
this.message = '';
}.bind(this), 2500);
}
return false;
}
logout(): boolean {
this.authService.logout();
return false;
}
}
login.component.html:
<h1>Login</h1>
<div class="alert alert-danger" role="alert" *ngIf="message">
{{ message }}
</div>
<form class="form-inline" *ngIf="!authService.getUser()">
<div class="form-group">
<label for="username">User: (type <em>user</em>)</label>
<input class="form-control" name="username" #username>
</div>
<div class="form-group">
<label for="password">Password: (type <em>password</em>)</label>
<input class="form-control" type="password" name="password" #password>
</div>
<a class="btn btn-default" (click)="login(username.value, password.value)">
Submit
</a>
</form>
<div class="well" *ngIf="authService.getUser()">
Logged in as <b>{{ authService.getUser() }}</b>
<a href (click)="logout()">Log out</a>
</div>
What is in your authService.getUser() method? If it is asynchronous all you have to do is *ngIf="(authService.getUser() | async)".
I don't understand why are you using *ngIf="!authService.getUser()" inside your login component like this.
Semantically the purpose of this component is to be used when you're not logged.
So simply try to wrap your <app-login></app-login> in your app.component.html into a div wich have the *ngIf="!authService.getUser()"
Like this :
<div *ngIf="!authService.getUser()">
<app-login></app-login>
</div>
Also I recommand you to not use directly the service method like this in the html but a flag instead for example isLogged init to false and update it when the user successfully logged.
Your ng-if will be : *ngIf="!isLogged | async"

Controller not recognized by HTML after $state.go()

I'm fairly new to Angular and very new to using the ui-router, so I could be missing something obvious.
If I launch my results.html page on its own, everything from the Web API is bound correctly through the controller and shows up as expected.
When I start from index.html and click on the button that calls $state.go(), I am navigated to the results.html page .. but none of the data from the controller shows up. The controller & service are still being called though - because I put console.log() statements to verify that the object I want is being returned after $state.go() and it is - the template just isn't registering it.
Here is my code for my ui-router and main controller:
// script.js
var app = angular.module('BN', ['ui.router']);
// configure our routes
app.config(function ($locationProvider, $stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('');
$stateProvider
.state('default',{
url:'/',
templateURL:'index.html',
controller: 'MainController'
})
.state('results', {
url:'/results',
controller: 'ResultsController',
controllerAs: 'vm',
templateUrl: 'Results/Results.html'
})
.state('instructor', {
url:'/api/instructors/:id',
templateUrl: 'Instructors/Instructor.html'
});
$locationProvider.html5Mode(true);
});
app.controller('MainController', MainController);
function MainController ($state) {
var vm = this;
vm.Submit=function( ){
$state.go('results');
};
}
So Results.html renders perfectly fine launched on it's own, but when navigated to - the controller is called but not bound to the html template.
You have your index.html file set up properly, but after that you're using ui-router incorrectly.
In your index.html file where you have:
<body ui-view>
this tells ui-router to load the contents of your templates into the body of your document, so your templates should just be snippets of html to be rendered within your body tag. So you should delete everything from results.html until all that remains is this:
<div id="headerBar" >
<div class="form-group" id="headerBar" >
<input class="form-control input-lg" type="text" id="inputlg" placeholder="Zipcode" />
<button id="sub" class="btn btn-default btn-lg" type="submit" ng-click="vm.getInstructors()">Find an Instructor!</button>
</div>
</div>
<table>
<tr ng-repeat="Instructors in vm.instructors">
<td style="padding-top:5px;">
<div>
<nav class="navbar">
<div class="container-fluid">
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="searchString" >
</div>
<button type="submit" class="btn btn-default" value="Filter">Search</button>
</form>
</div><!-- /.container-fluid -->
</nav>
</div>
</td>
</tr>
</table>
<div class="col-md-8">
</div>
<aside class="sidebar" ui-view="map">MAP</aside>
A few other things. You have the controller setup in your routes, so you don't need to specify it anywhere in results.html. Also you should not be able to navigate to results.html. Instead you would just navigate to (your domain)/results.

AngularJS $rootScope not accessible in html page

I have looked for the solution in following two links:
how-to-access-rootscope-value-defined-in-one-module-into-another-module
rootscope-variable-exists-but-not-accessible
But still could not find a solution.
I initialize $rootScope.user variable in $scope.login function, which is triggered by some other button click event, of my controller as:
app.controller('LoginFormController',['$rootScope','$location','$log','$scope','userAngService','userBean',function($rootScope,$location,$log,$scope,userAngService,userBean){
$scope.login = function(val){
$scope.user = userAngService.login(val).then(function(data){
$rootScope.user = data;
$location.path("/home");
});
};
}]);
Redirecting it to /home mapped in app.js as:
angular.module('Writer', ['AllControllers','ngRoute'])
.config(['$routeProvider', function($routeProvider,$Log){
$routeProvider.when('/Diary',{
templateUrl:'login.html',
controller: 'LoginFormController'
})
.when('/home',{
templateUrl: 'home.html',
controller: 'ReachController'
})
.otherwise({redirectTo : '/Diary'});
}]);
Now I am accessing $rootScope.user variable in the mapped controller ReachController as:
app.controller('ReachController',['$scope','$rootScope',function($scope,$rootScope){
$scope.user = {};
$scope.user = $rootScope.user;
console.log($scope.user);
}]);
It is perfectly logging angular object in console but is not avaiable in my home.html page.
Here is the html page - accessing it in <h2> and <h3> tags:
<div>
<h2>{{$scope.user}}hhhello</h2>
<h3>{{$scope.user.author}}</h3>
<div id="welcomeStory">
<span id="wsTitleBub">Title</span>
<input id="wsTitle" type="text" ng-model="wsPublish.welcomeStoryTitle" />{{wsPublish.welcomeStoryTitle}}
<h6>Words..</h6>
<textarea id="wsWords" ng-model="wsPublish.welcomeStoryWords"></textarea>
<input id="wsPublish" type="button" name="wsPublish" value="Publish" ng-click="pub = !pub" />
<input id="wsAddShelf" type="button" name="wsAddToShelf" value="Add To Shelf" ng-click="addToShelf()" />
</div>
<div id="wsPublishTo" ng-show="pub">
<ul>
<li>
<input type=submit id="wsgroups" value="Group" ng-click="publishGroup(wsPublish)" />
</li>
<li>
<button id="wsPublic" ng-click="public()">Public</button>
</li>
</ul>
</div>
</div>
Just change your $scope.user to user in your markup and it'll work.
Once it is in $rootScope you can directly access it in markup with {{user}} no need to again assign it to scope variable!