I am trying to integrate google-recaptcha but no success.
Getting error
feedback.js:39 Uncaught TypeError: grecaptcha.render is not a function
main.js
'googlerecaptcha':'https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit',
define(['ojs/ojcore', 'knockout', 'jquery', 'appController', 'ckeditor', 'googlerecaptcha', 'ojs/ojlabel',
'ojs/ojknockout', 'ojs/ojinputtext', 'ojs/ojformlayout'],
function (oj, ko, $, app, ckeditor, grecaptcha) {
/**
* The view model for the main content view template
*/
function feedbackViewModel() {
var self = this;
// For small screens: labels on top
// For medium screens and up: labels inline
this.labelEdge = ko.computed(function () {
return app.smScreen ? "top" : "start";
}, this);
onloadCallback = function (a) {
grecaptcha.render('submit', {
'sitekey': 'YOUR_API_KEY',
'callback': self.onSubmit
}, true);
};
this.handleActivated = function (info) {
};
self.onSubmit = function (token) {
console.info("google recatpcha onSubmit", token)
//do validation/application code using token
var data = {secret: grecaptcha, response: recaptchaToken};
$.post({
url: "https://www.google.com/recaptcha/api/siteverify",
form: data
}).then(function (e) {
//recaptcha service called...check result
var resp = JSON.parse(e);
if (resp.success == false) {
console.info("recaptcha token outcome is false")
} else {
console.info("recaptcha token validated")
}
});
};
}
return feedbackViewModel;
});
Do you have a mapping for 'googlerecaptcha' in src/js/path_mapping.json? If I go to https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit, I do not see that it is returning any valid object. So most likely 'grecaptcha' variable is undefined.
reCaptcha + RequireJS
Looks like reCaptcha is a function that has to be executed vs an object that can be interacted with directly. So you may need a different approach, something mentioned in this thread.
Related
I've been working on this app for a while. I have several other modules that all work fine. I've been having a ton of trouble with this particular module and it's super frustrating. This problem looks super simple. Maybe I'm over thinking it. Hopefully someone will say that I am. :)
In this module, I decided to use methods from my model. This particular one is non-instanced. Here is my model:
/*
* Account.js
*/
module.exports = {
connection: 'islMongo',
attributes: {
name: {
type: 'string',
required: true,
},
},
numberToName: function(accountNumber) {
Account.findOne(accountNumber).exec(function(err, a){
if (err) {
return 'err';
} else {
return 'ok';
}
});
return 'broke';
},
};
I call it from one of my controllers like this:
var accountName = Account.numberToName(params.id);
At this point accountName's value is "broke". I don't understand why it wouldn't either return "err" or "ok". I simplified my actual function here for testing.
Edit:
I have other calls that work properly. For instance:
updateBalance: function(account, amount, callback) {
/* Accepts account id or account object */
(function _lookupAccount(afterLookup) {
if (typeof account === 'object') return afterLookup(null, account);
Account.findOne(account)
.exec(afterLookup);
})(function (err, a) {
if (err) return callback(err);
if (!a) {
err = new Error();
err.message = "Couldn't find account.";
err.status = 400;
return callback(err);
}
a.balance = parseInt(a.balance) + parseInt(amount);
a.save(callback);
});
},
Is called like this:
Account.updateBalance(params.account, -2000);
The definition has a callback, but I don't actually use one because it isn't needed. The method works fine.
Sails.js documentation provides example methods that don't use callbacks. They simply return the requested data.
// Attribute methods
getFullName: function (){
return this.firstName + ' ' + this.lastName;
},
isMarried: function () {
return !!this.spouse;
},
isEligibleForSocialSecurity: function (){
return this.age >= 65;
},
encryptPassword: function () {
}
And called like this:
if ( rick.isMarried() ) {
// ...
}
Which is what I am trying to do with my method at the top of this post. It seems like the exec() portion of Account.findOne() isn't even being called.
Sails.js & Node.js are asynchronous. So in simple words they don't wait for response from database, but when they got date they call a callback. So you need to read about Queries and callbacks and what is callback hell (you should never do that).
And now get back to your problem.
/*
Account.js
*/
//...
numberToName: function(accountNumber, callback) {
// if you want some additional logic you can create function here and call callback in it
Account.findOne(accountNumber).exec(callback);
}
//...
Tip: callbacks first param is always error.
// AccountController
method: function(req, res){
var id = req.param('id'); // if its int you should parseInt()
var callback = function(error, account){
if(error)
res.send('error');
else
res.send(account.name);
};
Account.numberToName(id, callback);
}
I have a react component - coursePage.js
function getCourseInitState(){
return {
courses: CourseStore.getAllCourses()//courseStore is required in script
};
}
var Courses = React.createClass({
getInitialState: function(){
return getCourseInitState();
},
render: function () {
return (
<div>
<h1> Course </h1>
<CourseList courses={this.state.courses} />
</div>
);
}
});
Action file -courseAction
var CourseAction = {
CourseList: function(){
var courseList = CourseApi.getAllCourses();
Dispatcher.dispatch({
actionType: ActionTypes.COURSE_INITIALIZE,
courseList: courseList
});
}
Store File - courseStore
var CourseStore = assign({}, EventEmitter.prototype, {
addChangeListener: function(callback){
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback){
this.removeListener(CHANGE_EVENT, callback);
},
emitChange: function(){
this.emit(CHANGE_EVENT);
},
getAllcourses: function(){ //here is the function define
return _courses;
},
getCourseById: function(id){
return _.find(_courses, {id: id});
}
});
Dispatcher.register(function(action){
switch(action.actionType){
case ActionTypes.COURSE_INITIALIZE:
_courses = action.CourseList;
CourseStore.emitChange();
break;
}
});
module.exports = CourseStore;
in console I am getting "Uncaught TypeError: CourseStore.getAllCourses is not a function"
I don't want to call api directly in my coursePage.js so I find this way of initialising the page but it is not working.
(Please note - I am new to this) As per my recent learning Action file must always call API and send the request to State. I can load with help of componentWillMount function. But, I wanted to solve with this.If not wrong, then it is more neat and preferable way of implementing?
You have a typo -> getAllcourses in the Store and in the Component you call getAllCourses
getAllCourses: function(){ //Should be getAllCourses instead of getAllcourses
return _courses;
},
Im learning Angular JS im using a REST api in slim that returns JSON data objects. I have a search controler where i have a submitform method wich gets data. But now i have another controler that also needs this data. now i have read about this and found that it can be don using a factory service but for some reason im getting this error:
TypeError: undefined is not a function
at http://localhost/c2dmobile/js/main.js:72:23
at https://code.angularjs.org/angular-1.0.0.min.js:8624:11
at wrappedCallback (https://code.angularjs.org/angular-1.0.0.min.js:6585:59)
at https://code.angularjs.org/angular-1.0.0.min.js:6622:26
at Object.Scope.$eval (https://code.angularjs.org/angular-1.0.0.min.js:7769:28)
at Object.Scope.$digest (https://code.angularjs.org/angular-1.0.0.min.js:7641:25)
at Object.Scope.$apply (https://code.angularjs.org/angular-1.0.0.min.js:7855:24)
at done (https://code.angularjs.org/angular-1.0.0.min.js:8844:20)
at completeRequest (https://code.angularjs.org/angular-1.0.0.min.js:8984:7)
at XMLHttpRequest.xhr.onreadystatechange (https://code.angularjs.org/angular-1.0.0.min.js:8954:11) angular-1.0.0.min.js:5525
(anonymous function) angular-1.0.0.min.js:5525
(anonymous function) angular-1.0.0.min.js:4659
wrappedCallback angular-1.0.0.min.js:6587
(anonymous function) angular-1.0.0.min.js:6622
Scope.$eval angular-1.0.0.min.js:7769
Scope.$digest angular-1.0.0.min.js:7641
Scope.$apply angular-1.0.0.min.js:7855
done angular-1.0.0.min.js:8844
completeRequest angular-1.0.0.min.js:8984
xhr.onreadystatechange
here is the code:
//SHARE DATA BETWEEN CONTROLLERS
c2dApp.factory("ShareData", function() {
return {
//ZipCode: function() {return ZipCode;},
resList: function() {return ResList;}
};
});
//CONTROLLERS: SEARCHLIST
c2dApp.controller('SearchResultController', function($scope, ShareData) {
//NEEDS THE RESTULT FROM SEARCH
});
//CONTROLLERS: SEARCH
c2dApp.controller("SeachController", function($scope, $http, ShareData) {
$scope.message = 'dit is search';
$scope.myData = {};
$scope.myData.haveZip = false;
$scope.searchForm = {};
$scope.searchForm.zipCode = "";
$scope.searchForm.getFormFieldCssClass = function(ngModelController) {
//console.log("getting css class: " + ngModelController.$valid) ;
if(ngModelController.$pristine) return "";
return ngModelController.$valid ? "fieldValid" : "fieldInvalid";
};
$scope.submitForm = function() {
//console.log("--> Submitting form");
$http({
url: "http://localhost/c2dapi/search",
data: $scope.searchForm,
method: 'POST',
headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
}).success(function(data){
//console.log("OK", data);
if (angular.equals(data[0], 'no_location_found')) {
console.log('geen lokatie gevonden');
}
if (angular.equals(data[0], 'restaurants_found')) {
console.log('restaurant lijst');
console.log(data);
ShareData.ResList() = data; // <------ REturns ERROR
}
}).error(function(err){"ERR", console.log(err)});
};
});
//UPDATE
cshion awnser works partial
ShareData.ResList() = data;
returns the error ReferenceError: Invalid left-hand side in assignment
so i changed it to; ShareData.ResList = data;
now the json objects are found when i call ShareData.ResList
but this is only after the post, i want to so something like
if (ShareData.ResList) {
}
the problem is that ShareData.ResList is never "undefined" but returns:
function () {
return ResList;
}
when its not set? i want it do return false.. how can i do this ?
You can share data between controllers , directives ,etc with Service or Factory.
Using factory:
c2dApp.factory("ShareData", function() {
var ResList;
return {
resList: function() {return ResList;}
};
});
In your controller:
ShareData.resList() = data
Iam build single page app in AngularJs,and I need call Facebook UI dialog.And if user click 'ok',or 'cancel',successReport methos not call immediately.This method call after i click on any button in page,or link.Similar to internal queue
service.showStreamDialog=function (json) {
if (json.stream) {
var newCardSentId = json.cardSentId;
FB.ui(json.stream, function (resp) {
if (resp && resp.post_id) {
reportService.successReport(newCardSentId,newCardSentId,resp.post_id);
} else {
reportService.cancelReport(newCardSentId);
}
});
}
};
// in other file
var successReport=function(cardId,cardSentId,postId){
var defered = $q.defer();
$http.post(reportUrl,$.param({
cardId:cardId,
cardSentId:cardSentId,
postId:postId,
accessToken: ACCESS_TOKEN
}))
.success(function(data){
defered.resolve(data);})
.error(function(data){
defered.reject(data);
});
return defered.promise;
};
I found problem. It was in integration facebook api in my app.I add $rootScope.$apply call,
and all working as i expected
service.showStreamDialog = function (json) {
if (json.stream) {
var newCardSentId = json.cardSentId;
FB.ui(json.stream, function (resp) {
if (resp && resp.post_id) {
$rootScope.$apply(function () {
$rootScope.$broadcast('CARD_SENT_SUCCESS', {cardSentId: newCardSentId,post_id:resp.post_id});
});
} else {
$rootScope.$apply(function () {
$rootScope.$broadcast('CARD_SENT_CANCEL', {cardSentId: newCardSentId});
});
}
});
}
};
I'm using Bootstrap Typeahead to suggest som search results. The results are returned from a ajax ressource, and since this resource creates a delay, I'm experiencing a unfortunate effect.
Example:
If typing a 4 letter word, the suggestions will appear after 2 letters, I can then go through the results with the keys up/down, but suddenly the suggestions will reload because the last request has finished.
Is there any way to "cancel" any remaining, if user is currently using the keys up/down to go through the suggestions?
('#query').typeahead({
items: 4,
source: function (query,process) {
map = {};
$.getJSON('/app_dev.php/ajax/autosuggest/'+query, function (data) {
vehicles = [];
$.each(data, function(i,vehicle){
map[vehicle.full] = vehicle;
vehicles.push(vehicle.full);
});
process(vehicles);
});
},
updater: function (item) {
// do something here when item is selected
},
highlighter: function (item) {
return item;
},
matcher: function (item) {
return true;
}
});
I think the following will satisfy your needs (its hard to reproduce exactly) :
There is no easy way to abort a delayed response, but you could extend typeahead as I figured out here (without modifying bootstrap.js)
The concept is to catch keydown, detect if the event is KEY_UP or KEY_DOWN, set a flag is_browsing, and then abort process if is_browsing is true (that is, if the user has hitted KEY_UP or KEY_DOWN and no other keys afterwards).
Extending typeahead :
// save the original function object
var _superTypeahead = $.fn.typeahead;
// add is_browsing as a new flag
$.extend( _superTypeahead.defaults, {
is_browsing: false
});
// create a new constructor
var Typeahead = function(element, options) {
_superTypeahead.Constructor.apply( this, arguments )
}
// extend prototype and add a _super function
Typeahead.prototype = $.extend({}, _superTypeahead.Constructor.prototype, {
constructor: Typeahead
, _super: function() {
var args = $.makeArray(arguments)
// call bootstrap core
_superTypeahead.Constructor.prototype[args.shift()].apply(this, args)
}
//override typeahead original keydown
, keydown: function (e) {
this._super('keydown', e)
this.options.is_browsing = ($.inArray(e.keyCode, [40,38])>-1)
}
//override process, abort if user is browsing
, process: function (items) {
if (this.options.is_browsing) return
this._super('process', items)
}
});
// override the old initialization with the new constructor
$.fn.typeahead = $.extend(function(option) {
var args = $.makeArray(arguments),
option = args.shift()
// this is executed everytime element.modal() is called
return this.each(function() {
var $this = $(this)
var data = $this.data('typeahead'),
options = $.extend({}, _superTypeahead.defaults, $this.data(), typeof option == 'object' && option)
if (!data) {
$this.data('typeahead', (data = new Typeahead(this, options)))
}
if (typeof option == 'string') {
data[option].apply( data, args )
}
});
}, $.fn.typeahead);
This typeahead-extension could be placed anywhere, eg in a <script type="text/javascript"> -section
Testing the extension :
<input type="text" id="test" name="test" placeholder="type some text" data-provide="typeahead">
<script type="text/javascript">
$(document).ready(function() {
var url='typeahead.php';
$("#test").typeahead({
items : 10,
source: function (query, process) {
return $.get(url, { query: query }, function (data) {
return process(data.options);
});
}
});
});
</script>
A "serverside" PHP script that returns a lot of randomized options with forced delay, typeahead.php :
<?
header('Content-type: application/json');
$JSON='';
sleep(3); //delay execution in 3 secs
for ($count=0;$count<30000;$count++) {
if ($JSON!='') $JSON.=',';
//create random strings
$s=str_shuffle("abcdefghijklmnopq");
$JSON.='"'.$s.'"';
}
$JSON='{ "options": ['.$JSON.'] }';
echo $JSON;
?>
It really seems to work for me. But I cannot be sure that it will work in your case. Let me now if you have success or not.