Backbone error when I pass a parameter on URL - backbone.js

This is my code:
<!DOCTYPE html>
<html>
<head>
<title>Bakbone pushStat</title>
<script type="text/javascript" src="vendor/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="vendor/underscore-min.js"></script>
<script type="text/javascript" src="vendor/backbone-min.js"></script>
<script type="text/javascript">
(function($){
var AppRouter = Backbone.Router.extend({
routes: {
"/": "initHome",
"home": "initHome",
"projects/(:id)" : "initProject"
}
});
var app_router = new AppRouter;
app_router.on('route:initHome' , function(){
alert('initHome');
});
app_router.on('route:initProject' , function(id){
alert('Projet');
});
$(document).on("click",".links",function(e) {
var href = $(this).attr("href");
var url = lang + "/" + href;
page = $(this).attr("data-id");
var param = $(this).attr("data-param");
if (typeof(param) == 'undefined') { param = ""; }
if(activepage != href && !main.hasClass("loadingPage")){
loader.show();
firstInit = false;
activepage = href;
res = app_router.navigate(url, true);
getContent(page,param);
}
return false;
});
Backbone.history.start({pushState: true, root: "/backbone_pushStat/"});
})(jQuery);
</script>
</head>
<body>
HOME<br/>
TEST<br/>
<div id="default">default</div>
<div id="entrees">entrees</div>
</body>
</html>
When I click the HOME link, it works very well.
But, I don’t know why, I get this error when I click the TEST link (firefox console).
SyntaxError: syntax error
backbone-min.js (ligne 1)
ReferenceError: jQuery is not defined
})(jQuery);
Anything wrong with my code?
Please help.

Related

AngularJs with REST Api

i'm new to angularJs and want to learn more about it, i'm trying to display some users from a fake REST Api, when trying to run my code i got empty page and the console doesn't give me any errors , i don't know where is the error or where i can debug.
app.js
var myApp = angular.module("app", []);
contactsData.service.js look like that :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http) {
var self = this;
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
var promise2 = promise1.then(function (response) {
return response.data;
});
return promise2;
}
});
})();
contacts.controller.js
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl(contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
this.contacts = data;
});
}
})();
finally my view index.html
<html ng-app="app">
<head>
<title></title>
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="contacts.controller.js"></script>
<script src="contactsData.service.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" />
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
</head>
<body class="container">
<div>
<div ng-controller="contactsCtrl as ctrl">
<div class="raw">
<ul class="list-group">
<li class="li-group-item" ng-repeat="obj in ctrl.contacts">
{{obj.name.title + " " + obj.name.first + " " + obj.name.last}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
Small correction required in your contactsCtrl
function contactsCtrl(contactDataSvc) {
var vm = this;
contactDataSvc.getContacts()
.then(function(data){
vm.contacts = data;
});
}
You cannot use this inside the then callback as the scope will be different.
Corrected working example here : http://plnkr.co/edit/LLKJipkBbiZ17QjQpw1X
Refer more:
https://www.w3schools.com/js/js_scope.asp
What is the scope of variables in JavaScript?
1 - Is this url correct? http://localhost:3000/contacts
2 - Open the url on any browser, does it return any response ? JSON?
Please check this first to see if the problem is not on the server side.
Firstly inject $scope in controller because anything/data that we want to access over Html from controller needs to be binded on $scope.
So you controller would look like:
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl($scope,contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
$scope.contacts = data;
});
}
})();
Secondly from the service you need to return a promise from it only then you will be able to get the data once the response is back from the API.
So,the updated service code is :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http,$q) {
var self = this;
var defered = $q.defer();
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
promise1.then(function (response) {
defered.resolve(response.data);
});
return defered.promise;
}
});
})();

Angular login auth what about using web worker?

What do you think about this approach
using web worker for angular login/auth
it looks good at me and in this way you can get rid of
$rootScope event as well :)
This is just an example in a more prodution way
you should use like https://stackoverflow.com/a/16730809
Html & js
<html ng-app="app">
<head>
<meta charset="utf-8">
<title>Form</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body ng-controller="LoginController as vm">
<p ng-if="vm.isLogged">Logged as {{vm.username}}</p>
<a href ng-click="vm.doFakeLogin()">Login</a>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.2/angular.min.js">
</script>
<script>
function LoginController($scope){
var vm = this;
vm.isLogged = false;
var workerCheckLogin = new Worker('worker-check-login.js');
var workerDoLogin = new Worker('worker-do-login.js');
var jwt = 'auth-token';
workerCheckLogin.postMessage(jwt);
workerCheckLogin.addEventListener('message', function(e) {
if(e.data > 0){
$scope.$evalAsync(function() {
vm.isLogged = true;
vm.username = 'Whisher';
});
}
}, false);
vm.doFakeLogin = function doFakeLogin(){
workerDoLogin.postMessage({username:'whisher','password':'12345'});
}
workerDoLogin.addEventListener('message', function(e) {
if(e.data > 0){
$scope.$evalAsync(function() {
vm.isLogged = true;
vm.username = 'Whisher';
});
}
}, false);
}
angular
.module('app', [])
.controller('LoginController',LoginController);
</script>
</body>
</html>
worker-check-login.js
self.addEventListener('message', function(e) {
console.log('Worker check login said: ', e.data);
/*
do xhr to the server
e.data = jwt
return
1 succees
0 fail
*/
self.postMessage(0); //
}, false);
worker-do-login.js
self.addEventListener('message', function(e) {
console.log('Worker do login said: ', e.data);
/*
do xhr to the server
e.data = credentials
return
1 succees
0 fail
*/
self.postMessage(1); //
}, false);

Marionette 'could not find template' - load external templates

I'm new with backbone, and also marionette. Idk why I'm get this error. My structure seems correct, but the error persists.
This is my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<!-- Main App -->
<div id="main-area"></div>
<!-- Templates -->
<script id="main-tpl" src="templates/main.tpl" type="text/x-template"></script>
<!-- 3rd party Dependencies -->
<script src="vendor/jquery/dist/jquery.js"></script>
<script src="vendor/underscore/underscore.js"></script>
<script src="vendor/backbone/backbone.js"></script>
<script src="vendor/backbone.wreqr/lib/backbone.wreqr.js"></script>
<script src="vendor/backbone.babysitter/lib/backbone.babysitter.js"></script>
<script src="vendor/marionette/lib/backbone.marionette.js"></script>
<script type="text/javascript">
// External templates load
_.each(document.querySelectorAll('[type="text/x-template"]'), function (el) {
$.get(el.src, function (res) {
el.innerHTML = res;
});
});
var App = new Backbone.Marionette.Application();
_.extend(App, {
Controller: {},
View: {},
Model: {},
Page: {},
Scrapers: {},
Providers: {},
Localization: {}
});
App.addRegions({
Main: '#main-area'
});
App.addInitializer(function (options) {
var mainView = new App.View.Main();
try {
App.Main.show(mainView);
} catch(e) {
console.error('Error on Show Main: ', e, e.stack);
}
});
App.View.Main = Backbone.Marionette.Layout.extend({
template: '#main-tpl'
});
(function(App) {
'use strict';
App.start();
})(window.App);
</script>
</body>
and my template/main.tpl is only test html.
<div>sounds</div>
All 3rd party dependencies paths are correct.
The error that appears is this:
Error: Could not find template: '#main-tpl'
Can someone tell me where am I wrong?
Thanks.
EDIT:
I think the problem is because $.get is async and the template load after backbone try to render, how can I solve this?
You can update your HTML and replace
<script id="main-tpl" src="templates/main.tpl" type="text/x-template"></script>
with
<script id="main-tpl" type="text/html">
--- template code ---
</script>
Or use requireJs !text plugin to load template files into marionette views.
The problem is that the template loads after the app initialization.
Instead, try this:
$(function () {
var tplList = document.querySelectorAll('[type="text/x-template"]');
var tplCounter = 0;
_.each(tplList, function (el) {
$.ajax({
'url': el.src,
success: function (res) {
el.innerHTML = res;
++tplCounter;
if(tplCounter == tplList.length){
App.start();
}
}
});
});
});
define(['marionette','tpl!cell.tpl'],function(tpl){
var Mn = Backbone.Marionette;
var MyView = Mn.View.extend({
className: 'bg-success',
template: tpl,
regions: {
myRegion: '.my-region'
}
});
})
var model = new Backbone.Model({});
var myView = new MyView({model:model});

Phonegap with Angular: deviceready not working properly

I believe I have set everything for Angular to work in Phonegap, but apparently the deviceready function is not having the behavior that I expect.
So here is how I set:
index.html
<html ng-app="app">
<head>
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/lib/ready.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
<div class="header" ng-controller="HeaderController">
<h3 id="logo"><img src="img/logo.png"/></h3>
<p>{{title}}</p>
<button ng-click="changeTitle()"></button>
</div>
</body>
</html>
app.js
$app = angular.module('app', ['fsCordova']);
$app.config(function($compileProvider){
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
});
$app.controller('HeaderController', function($scope, CordovaService) {
CordovaService.ready.then(function() {
console.log("Setting the title");
$scope.title = "This title";
$scope.changeTitle = function() {
console.log("Changing the title");
$scope.title = "Title changed";
}
});
});
ready.js from: http://www.ng-newsletter.com/posts/angular-on-mobile.html#native
angular.module('fsCordova', [])
.service('CordovaService', ['$document', '$q',
function($document, $q) {
var d = $q.defer(),
resolved = false;
var self = this;
this.ready = d.promise;
document.addEventListener('deviceready', function() {
resolved = true;
d.resolve(window.cordova);
});
// Check to make sure we didn't miss the
// event (just in case)
setTimeout(function() {
if (!resolved) {
if (window.cordova) d.resolve(window.cordova);
}
}, 3000);
}]);
The title is appearing the way it is {{title}}, not its value. When I click the button, nothing happens, not even the debug logs on the console. Any tips how to set Angular on Phonegap? Thanks.
Apparently on angular 1.2 the urlSanitizationWhitelist doesn't exist anymore.
So I just had to remove the $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/); line and it worked

Phonegap.js on second html page

I basically have two pages in my phonegap application that I am building with PGB (index.html and main.html), that both use angular.js. Index.html is a login for the app, which redirects to main.html afterwards. All my plugins and phonegap.js are being injected fine into main, but none of the inline JS (alerts on doc ready, device ready, window load) are firing, let alone phonegap.js being loaded as well.
Any advice would be appreciated.
Script Includes:
<script src="phonegap.js"></script>
<script src="cdv-plugin-fb-connect.js"></script>
<script src="facebook-js-sdk.js"></script> <script>alert("inside pg");</script>
<script src="childbrowser.js"></script>
<script src="js/jquery.js"></script>
<script src="js/angular.min.js"></script>
<script>alert("here");</script>
<script src="js/controllers.js"></script>
<script src="js/klass.min.js"></script>
<script src="js/code.photoswipe.jquery-3.0.5.min.js"></script>
<script src="js/maskedInput.js" type="text/javascript"></script>
<script src="js/jquery.joyride.js"></script>
<script src="js/jquery.fancybox.pack.js"></script>
<script src="http://connect.facebook.net/en_US/all.js" type="text/javascript"></script>
Scripts:
alert("p2 adding")
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is loaded and it is now safe to make calls PhoneGap methods
//
function onDeviceReady() {
alert("main.html: device is ready");
}
$(window).load(function(){
alert("window.load happening");
})
</script>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-42023187-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-42023187-1', 'openvino.com');
ga('send', 'pageview');
</script>
<script type="text/javascript">
var objectToLike = window.location;
var FBactivated = false;
FB.init({
appId : '659381964079214', // App ID
channelURL : '', // Channel File, not required so leave empty
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true,
xfbml : true // parse XFBML
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
getFriends();
testAPI();
FBactivated = true;
}
});
function getFriends() {
var fbUserIDs = []
FB.api('/me/friends', function(response) {
if(response.data) {
$.each(response.data,function(index,friend) {
var id = friend.id;
fbUserIDs.push(id);
});
var dataString = "fbUserIDs="+fbUserIDs.join();
$.ajax({
type: "POST",
data: dataString,
async: false,
url: "http://m.openvino.com/Scripts/faveMatch.php"
}).done(function(data){
console.log(data);
window.localStorage.setItem("fbFriends", data);
console.log("Saved");
});
} else {
alert("Error!");
}
});
}
function testAPI() {
FB.api('/me', function(response) {
//console.log(response, response.email);
var dataString2 = "id=" + response.id;
dataString2 += "&first_name=" + response.first_name;
dataString2 += "&last_name=" + response.last_name;
dataString2 += "&email=" + response.email;
console.log(dataString2);
$.ajax({
type: "POST",
url: "http://m.openvino.com/Scripts/fbconnect.php",
data: dataString2
}).done(function(data){
var dataJSON = $.parseJSON(data);
if (dataJSON[0].STATUS == "FAILURE") {
//console.log(dataJSON[0].MESSAGE);
return false;
} else if (dataJSON[0].STATUS == "SUCCESS") {
window.localStorage.setItem('email',dataJSON[0].COOKIE.email);
window.localStorage.setItem('password',dataJSON[0].COOKIE.password);
window.localStorage.setItem('name_first',dataJSON[0].COOKIE.name_first);
window.localStorage.setItem('name_last',dataJSON[0].COOKIE.name_last);
window.localStorage.setItem('uID',dataJSON[0].COOKIE.uID);
window.localStorage.setItem('phone',dataJSON[0].COOKIE.phone);
window.localStorage.setItem('firstTime',dataJSON[0].COOKIE.firstTime);
}
});
});
}
function fbLogout() {
if (FBactivated) {
try {
FB.logout(function(response) {
window.location.href = "index.html";
});
} catch (err) {
window.location.href = "index.html";
}
} else {
window.location.href = "index.html";
}
}
$(document).ready(function() {
alert("document.ready loaded");
$("#logmeout").click(function(e){
e.preventDefault();
window.localStorage.clear();
fbLogout();
return false;
});
$('.back_btn').click(function(e) {
$('.profile_menu').hide();
history.back();
});
$(document).click(function(e) {
$('.profile_menu').hide();
})
$('.profile_btn').click(function(e) {
$('.profile_menu').slideToggle();
e.stopPropagation();
e.preventDefault();
return false;
});
$('.profile_menu a').each(function() {
$(this).click(function(e) {
$('.profile_menu').hide();
});
});
});
HTML:
<body ng-app="OpenVino">
<div id="fb-root"></div>
<div class="header-wrap">
<header>
<div ng-show="(page != 'list')" class="back_btn"></div>
<img src="imgs/logo_only.png" alt="OpenVino" />
<div class="profile_btn"></div>
</header>
</div>
<div class="profile_menu">
My Favorites
Contact OpenVino
Images
Logout
</div>
<div class="content {{page}}" ng-view></div>
I fixed it with a simple, but disheartening solution: You have to turn your multipage app into a one page app. Unfortunate how phonegap advertises that you can take your HTML, CSS, and JS and build it natively. All of the .js loaded on the second page wouldnt work until I changed my login to a partial and fooled around with the routing.

Resources