I am using stripe payment to process payments. I followed this GITHUB project and this blog.
My project has nested views and uses routers as well.
My project structure looks like
src
app
views
controllers
directives
index.html
app.js
The app.js is where angular module is loaded manually and has the routers.
app.js
var myApp = angular.module('myApp', ['ui.router', 'formData']);
myApp.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
// routers
}
The index.html is where the angular and stripe scripts are included
index.html
<head lang="en">
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<Script src="resources/angular.min.js"></Script>
<Script src="resources/angular-ui-router.min.js"></Script>
<script src="app.js"></script>
<script src="directives/formData/formData.js"></script>
<script type="text/javascript"
src="resources/angular-payments.js">
</script>
<script>
Stripe.setPublishableKey('key')
</script>
</head>
<div>
<div ui-view>
</div>
</div>
Now the formData directive is where I am trying to include the strip payment
formData.js
var formData = angular.module('formData',['angularPayments']);
formData.directive('formData',function(){
return {
restrict: 'EA',
scope: {},
replace: true,
link: function($scope, element, attributes){
},
controller: function($scope,$attrs,$http, $state){
//This is the callback for strip from the links above as followed
$scope.stripeCallback = function (code, result) {
console.log("inside cc callbakc");
if (result.error) {
console.log("credit card error");
window.alert('it failed! error: ' + result.error.message);
} else {
console.log(result);
console.log("credit card succes "+result.id);
window.alert('success! token: ' + result.id);
}
};
},
templateUrl: 'directives/formData/formData.tpl.html'
}
});
formData.tpl.html has another ui router
formData.tpl.html
<form id="signup-form" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div ui-view></div
</form>
and one of the ui router html page is the payment page with this code
<form stripe-form="stripeCallback" name="checkoutForm">>
<input ng-model="number" placeholder="Card Number"
payments-format="card" payments-validate="card" name="card" />
<input ng-model="expiry" placeholder="Expiration"
payments-format="expiry" payments-validate="expiry"
name="expiry" />
<input ng-model="cvc" placeholder="CVC" payments-format="cvc" payments-validate="cvc" name="cvc" />
<button type="submit">Submit</button>
</form>
I get the validations working but nothing prints in the console when I hit submit. I guess the js is not being fired. Let me know if you need more information.
This will render as nested forms, which is invalid html. Most browsers are silently 'forgiving' of this by treating the inner form as a non-form element.
If you move the checkoutForm out from the signup-form, this should put you on the right track.
Related
I have read posts related to the same issue and cross verified my code but the problem persists.
Following is my index.html file
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-route.js"></script>
<link href="Scripts/styles.css" rel="stylesheet" />
<meta charset="utf-8" />
</head>
<body>
<table style="font-family:Arial">
<tr>
<td class="header" colspan="2" style="text-align:center">Website Header</td>
</tr>
<tr>
<td class="leftMenu">
Home<br/>
Courses<br />
Students<br />
</td>
<td class="mainContent">
<div><ng-view></ng-view></div>
</td>
</tr>
</table>
</body>
</html>
script.js file
/// <reference path="angular-route.js" />
/// <reference path="angular.js" />
var myModule = angular.module("myModule", ["ngRoute"])
.config(function ($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "Templates/home.html",
controller: "homecontroller",
})
.when("/courses", {
templateUrl: "Templates/courses.html",
controller: "coursescontroller",
})
.when("/students", {
templateUrl: "Templates/students.html",
controller: "studentscontroller",
})
.controller("homeController", function ($scope) {
$scope.message = "HomePage";
})
.controller("coursesController", function ($scope) {
$scope.courses = ["c","c++","c#"];
})
.controller("studentsController", function ($scope) {
$scope.students = [{ name: "Chandu", id: 1, gender: "female" }, { name: "Suma", id: 2, gender: "female" }, { name: "Arin", id: 3, gender: "male" }];
})
})
I have defined home, courses and students html files. After initial loading, when I click on any of the links for eg. home, /#/home is getting appended to the url but the partial template is not loading.
At first, I did not get any console errors also. But now I am getting the following error even though the name of myModule is correctly used in both script.js and index.html files
Uncaught Error: [$injector:modulerr] Failed to instantiate module myModule due to:
Error: [$injector:nomod] Module 'myModule' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.5.9/$injector/nomod?p0=myModule
I very much appreciate any assistance to resolve my issue and help me find out where I am going wrong.
P.S: Index.html is in main directory and partial templates are in templates folder in main directory. And I am using version 1.5.9 of both angular.js and angular-route.js
you haven't added the module js file to your html page. You are only loading the angular libraries you need to add the script.js file after your angular libraries. The error is stating it can't find the module because it hasn't been loaded.
In the header you need to add the following
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-route.js"></script>
<script src="Scripts/script.js"></script><!-- loading your module -->
<link href="Scripts/styles.css" rel="stylesheet" />
<meta charset="utf-8" />
You forgot to add the main js file. And,
Try change the code to this:
<td class="leftMenu">
Home<br/>
Courses<br />
Students<br />
</td>
This might solve the problem.
Checking out your code it looks like you forgot to include script.js in your html code. Please include that file
<script src="your-path/script.js"></script>
after
<script src="Scripts/angular-route.js"></script>
And yes another thing is you have got error in your script.js file too. Check out your code, all those controllers must be out of that config.
Example:
angular.module('module-name', [])
.config(function() {
//
})
.controller('controller-name', function() {
//
});
Your links are missing the hashPrefix '!'.
This prefix appears in the links to client-side routes, right after the hash (#) symbol and before the actual path (e.g. index.html#!/some/path).
Given your HTML where hashPrefix is added to the links:
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.0/angular-route.js"></script>
<script src="script.js"></script>
<meta charset="utf-8" />
</head>
<body>
<table style="font-family:Arial">
<tr>
<td class="header" colspan="2" style="text-align:center">Website Header</td>
</tr>
<tr>
<td class="leftMenu">
Home<br/>
Students<br />
</td>
<td class="mainContent">
<div>
<ng-view></ng-view>
</div>
</td>
</tr>
</table>
<script type="text/ng-template" id="home.html">
Content of HOME template.
</script>
<script type="text/ng-template" id="students.html">
Content of STUDENTS template.
</script>
</body>
</html>
And your angular module:
var myModule = angular.module("myModule", ["ngRoute"])
.config(function ($locationProvider, $routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "home.html",
controller: "homeController"
})
.when("/students", {
templateUrl: "students.html",
controller: "studentsController"
})
})
.controller("homeController", function ($scope) {
console.log('This is home controller');
})
.controller("studentsController", function ($scope) {
console.log('This is students controller');
});
It works.
I'm learning Angular through a YouTube tutorial series. In the tutorial, you create username and password inputs, and then you use a controller and ngRoute to bring up a dashboard.html page when successful credentials are used. The problem is that when clicking the button, nothing happens, whether the proper credentials are entered or not. Everything is working on the tutorial, and I have triple checked the code thoroughly, and mine looks just like the code in the tutorial. I'm sure I must be missing something though.
What I think:
There is an issue with the click event firing, so maybe there is an issue with how I am calling the function?
The tutorial uses an older angular version (1.3.14), and maybe things have changed? I'm using 1.4.9, but I looked up the api data for the ng-click directive, and all seems well. I also tried using the older version to no avail.
I'm doing something wrong with ngRoute, potentially $scope misuse?
I am inserting all of the code below. Thanks for taking a look!
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Place Title Here</title>
<meta charset = "utf-8"/>
<meta http-equiv="X-UA-compatible" content="IE-edge, chrome=1">
<meta name = "viewport" content = "width = device - width, initial-scale = 1.0"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app="mainApp">
<div ng-view></div>
</body>
</html>
login.html
<div ng-controller="loginCtrl"></div>
<form action="/" id="myLogin">
Username: <input type="text" id="username" ng-model="username"><br>
Password: <input type="password" id="password" ng-model="password"><br>
<button type="button" ng-click="submit()">Login</button>
</form>
controller.js
var app = angular.module('mainApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'login.html'
})
.when('/dashboard', {
templateUrl: 'dashboard.html'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('loginCtrl', function($scope, $location) {
$scope.submit = function() {
var uname = $scope.username;
var password = $scope.password;
if($scope.username == 'admin' && $scope.password == 'admin') {
$location.path('/dashboard');
}
else {
alert('Nope')
}
};
});
dashboard.html
Welcome User.
Your form needs to be inside the div with ng-controller
<div ng-controller="loginCtrl">
<form action="/" id="myLogin">
Username: <input type="text" id="username" ng-model="username"><br>
Password: <input type="password" id="password" ng-model="password"><br>
<button type="button" ng-click="submit()">Login</button>
</form>
</div>
Otherwise it won't have access to the submit() function.
AngularJS is new to me (and difficult). So I would like to learn how to debug.
Currently I'm following a course and messed something up. Would like to know how to interpret the console error and solve the bug.
plnkr.co code
index.html
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form action="searchUser" ng-submit="search(username)">
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="submit" value="search">
</form>
<div>
<p>Username found: {{user.name + error}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function($scope, $http) {
var onUserComplete = function(response) {
$scope.user = response.data;
};
var onError = function(reason) {
$scope.error = "could not fetch data";
};
$scope.search = function(username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
};
$scope.username = "angular";
$scope.message = "GitHub Viewer"; };
app.controller("MainController", MainController);
}());
The console only says
searchUser:1 GET http://run.plnkr.co/lZX5It1qGRq2JGHL/searchUser? 404
(Not Found)
Any help would be appreciated.
In your form, action you have written this
<form action="searchUser"
What this does is it will try to submit to a url with currentHostName\searchUser, so in this case your are testing on plunker hence the plunker url.
You can change the url where the form is submitted. Incase you want to search ajax wise then you dont even need to specify the action part. You can let your service/factory make that call for you.
Though not exactly related to debugging this particular error, there is a chrome extension "ng-inspector" which is very useful for angularJS newbies. You can view the value each of your angular variable scopewise and their value. Hope it helps!
Here is the link of the chrome extension: https://chrome.google.com/webstore/detail/ng-inspector-for-angularj/aadgmnobpdmgmigaicncghmmoeflnamj?hl=en
Since you are using ng-submit page is being redirected before the response arrives and you provided any action URL as searchUser which is not a state or any html file so it being used to unknown address, it is async call so it will take some time you can use input types as button instead of submit.
Here is the working plunker.
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form >
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="button" ng-click="search(username)" value="search">
</form>
<div>
<p>Username found: {{user.name + error}} {{user}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
In my Ionic app, I want to pass parameter(s) from one sub-view to another sub-view. When I pass parameters first time, It works as I expected, but my problem is, when I return first sub-view and then go to another sub-view, it goes to that page without parameters. My code is given below:
index.html (project/www)
<!DOCTYPE html>
<html>
<head>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/main.js"></script>
<script src="js/routes.js"></script>
</head>
<body ng-app="app" animation="slide-left-right-ios7" >
<!-- main window -->
<div>
<ion-nav-view></ion-nav-view>
</div>
</body>
</html>
route.js (www/js/route.js)
angular.module('app.routes', [])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('mainUser', { // first window
url: '/mainuser',
templateUrl: 'templates/mainUser.html',
controller: 'mainCtrl'
})
.state('userDrive', { // second window
url: '/user_drive',
params: {
driveData: null // parameter send
},
templateUrl: 'templates/user_drive.html',
controller: 'DriveCtrl'
});
$urlRouterProvider.otherwise('/mainUser');
});
templates/mainUser.html
<ion-side-menus>
<ion-side-menu-content>
<ion-content class="padding" style="background-color:#fff;">
<input type="date" ng-model="selectData.selectedDate" placeholder="Date">
<input type="time" ng-model="selectData.selectedTime" placeholder="Time">
</ion-content>
<div class="bar bar-footer">
<div class="button-bar">
<a ui-sref="userDrive({ driveData: selectData })" class="button"> Drive </a>
</div>
</div>
</ion-side-menu-content>
</ion-side-menus>
Here after click on Drive button, it will redirect to userDrive sub-view with parameter driveData correctly. But where I back to mainUser and then change selectData.selectedDate and selectData.selectedTime and then click again on Drive button, it will redirect to userDrive sub-view without driveData parameter.
userDrive Controller
.controller('DriveCtrl', function($scope, $state, $stateParams) {
console.log("DriveCtrl"); // after redirect to this controller second time
// it also print no value
// seems might be DriveCtrl is not called
console.log("$stateParams : ", $stateParams);
})
The problem is that the view is cached by Ionic, and in that case the controller gets executed only once, so that's why you only see the log the first time.
You need to use ionic view events, here the docs: http://ionicframework.com/docs/api/directive/ionView/
#leandro-zubrezki is right. To remove cache you can add anywhere in the controller 'DriveCtrl'.
$scope.$on("$ionicView.afterLeave", function () {
$ionicHistory.clearCache();
});
U can't send object into state param, if u need to send each value separately
I have two angular apps on my page. First one is bootstrapped using the "ng-app" directive that is on the main body. Second app is initialized manually using angular.bootstrap method.
First app that is automatically bootstrapped
<body ng-cloak ng-app="app">
<section id="mainbody">
<div class="container radar-main-container">
#RenderBody()
</div>
</section>
Below is the app.js for the main app
var commonModule = angular.module('common', ['ui.router']);
var appMainModule = angular.module('app', ['common']);
Second app that is manually bootstrapping
#section footerScript {
angular.bootstrap(document.getElementById('signup'), ['signupApp']);
}
Html
<div id="signup" ng-app="signupApp" ng-controller="SignupController">
<div ui-view></div>
</div>
Controllers created in the second module:
signupModule.controller("SignupController", ['$scope', '$location',
function($scope, $location, $window) {
}
signupModule.controller("PackageInfoController", ['$scope', '$location',
function($scope, $location) {
}
When I run this code I get the error "SignupController" is not a function got undefined and it takes me to this link Error
Maybe this helps you out, since it works perfectly fine.
HTML template
<!DOCTYPE html>
<html>
<head>
...
<script src="app.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="AppCtrl">
main
</div>
<div id="signup" ng-controller="SignupCtrl">
signup
</div>
<script>
// #section footerScript
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('signup'), ['signup','common']);
});
</body>
</html>
app.js
var common = angular.module('common', []);
var app = angular.module('app', ['common']);
app.controller('AppCtrl', function($scope) {});
var signup = angular.module('signup', ['common']);
signup.controller('SignupCtrl', function($scope) {});
First of all,Your apps must not be nested (one inside another).You applications must be out it and not on body tag.
The second thing is,that you can use ng-app in you html file only one time.