FB.init and FB.ui doesn't work in IE7 in Canvas application - internet-explorer-7

Site I'm talking about is here:
https://www.facebook.com/kleenexau/app_295074103899059
If you run it in popular browsers - it works. If you run it in IE7 then it magically stops working. I was digging around more then 1 day so far, and decided to post this question here.
The code I'm using to connect to fb is:
<div id="fb-root"></div>
<script src="//connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript">
FB.init({
appId: _FBAPPID, xfbml: true, status: true, cookie: true, oauth: true,
channelUrl: "//sharethesoftness.kleenex.com.au/channel.php"
});
</script>
When you click the button this code is triggered:
function jumpToChoose(data) {
if(data) {
window.location = _SITE + "choose.html";
}
}
function startButtonClickHandler() {
$("#startButton").fadeOut();
$("#ajaxloader").fadeIn();
FB.ui({
method : "permissions.request",
"perms" : 'user_hometown,friends_hometown,email' /*publish_stream,user_about_me,friends_about_me,*/
}, jumpToChoose);
}
Adding 'http' to channelUrl doesn't work either. I have no clue what is causing this problem. I tried many solutions, also this: http://blog.coderubik.com/2011/03/cookies-and-facebook-canvas-apps/.
Any help would be appreciated. If you need any other details, let me know.

Try adding this at the very top of your page and see if it work.
<?php
header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
?>
It seems that IE is preventing you from storing third-party cookies, this header will enable your cookie to survive any privacy setting.

Related

AngularJS error [$injector:unpr] Unknown provider: in IE11

I couldn't find help in Google or here either. I'm new to Angular and I'm facing this error only in IE11 and below.
The error I'm getting is this:
My IE is in Portuguese so the translate of the first error is: it's not possible to get property of "getAttribute" of undefined or null
this is my app.config.js file
// Checking if an optional module is registered.
// If it's not, register an empty one to prevent errors.
(function(optDeps){
optDeps.forEach(function(dep){
try{
angular.module(dep);
}catch(e){
angular.module(dep, []);
}
})
})(['ui.carousel', 'ui.mask', 'vAccordion', 'ngAnimate']);
angular
.module('poletto', [
// Third party
'smoothScroll',
'ui.carousel',
'ui.mask',
'vAccordion',
'ngAnimate',
// Components
'poletto.components',
// Controllers
'poletto.controllers',
// Directives
'poletto.directives',
// Factories
'poletto.factories',
// Filters
'poletto.filters',
// Services
'poletto.services'
])
.constant('CONSTANTS', {
BASE_URL: document.currentScript.getAttribute('data-base-url')
})
.config(function($httpProvider){
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
})
.config(function($locationProvider){
if(window.history.pushState){
$locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
}
})
// Extending JQLite with a function that find nodes by className
.run(function(){
angular.element.prototype.findBySelector = function(selector){
var matches = [];
for(key in this){
// Pushing only HTMLElement's
if(this[key].nodeType){
// NodeList to array
var results = Array.prototype.slice.call(this[key].querySelectorAll(selector));
matches.push.apply(matches, results);
}
}
return angular.element(matches);
};
})
I've searched google and tried some solutions such as:
add <meta http-equiv="X-UA-Compatible" content="IE=11" />
wrap all my declarations in:
(function (angular) {
"use strict";
//code
}(window.angular));
add this in html tag:
<html lang="pt-br" xmlns:ng="http://angularjs.org">
Also I couldn't find any angular polyfills neither src/ folder, which I saw in a similar question with angular 2.
I don't know which file I should put here, so if you need some more info, you can ask me and I update the question.
Unfortunately document.currentScript is not supported on IE and can't be polyfilled so it can't done that way. Perhaps, you can embed the base url somewhere else or maybe add an id to your script and retrieve it in old school javascript.
<script id="main" data-base-url="https://my-api.com"></script>
And then retrieve it like this:
var currentScript = document.getElementById('main');
In your CONSTANTS provider you can do something like this:
.constant('CONSTANTS', {
BASE_URL: document.getElementById('main').getAttribute('data-base-url')
})
The problem stems from using document.currentScript, which isn't supported in IE 11 and apparently can't be polyfilled (easily at least). So you'll have to find a different way to declare your BASE_URL constant.

How can I implement the Plaid API using Ionic?

I was able to successfully implement the API on web, here is what it looks like, I have a button in a regular html file...
<div>
<span class="radio-button radio-left" id="sandboxLinkButton">Sandbox Mode</span>
</div>
I include the script tag...
<script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>
and I include the following javascript in the html body...
<script type="text/javascript">
var sandboxHandler = Plaid.create({
clientName: 'SUM',
env: 'tartan',
product: 'auth',
key: 'test_key',
onSuccess: function(token) {
//window.location = '/accounts.html?public_token=' + token;
console.log("yes");
},
});
// Open the "Institution Select" view using the sandbox Link handler.
document.getElementById('sandboxLinkButton').onclick = function() {
sandboxHandler.open();
};
</script>
Now I want to do the same using angular js. I'm using an ionic framework (not that it really matters). So I first display the necessary html using the following...
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/app');
$stateProvider
.state('app', {
url: '/app',
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
});
My menu.html file contains the following button...
<span ng-click="create()" class="radio-button radio-left" id="sandboxLinkButton">Sandbox Mode</span>
on ng-click it reaches the following controller. I tried to implement the API in this controller to no avail...
app.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
var sandboxHandler = Plaid.create({
clientName: 'SUM',
env: 'tartan',
product: 'auth',
key: 'test_key',
onSuccess: function(token) {
console.log("yes");
},
});
$scope.create = function() {
sandboxHandler.open();
}
});
I get the error Plaid is not defined in the controller. Why is that?
EDIT
I replicated a web app version using angular and it worked. I used the following CDN instead of the ionic/angular one
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
But I still can't get it to work on my ionic web app. Has anyone else ever come across this issue?
When I included the library I immediately got the following error in the browser: Uncaught TypeError: Cannot read property 'appendChild' of null
There are similar questions about this error regarding different libraries here and here, however I was not able to solve the problem based on those answers.
The closest thing to a solution that I found was in this issue report within the Plaid repository on GitHub. It describes a problem with the library not working when placed in the <head> tag. A commit within this issue report describes that this problem can be solved by including the script inside the <body> tag instead of the <head> tag.
I would recommend subscribing to the issue report to see whether other solutions will be introduced in the future.
So tldr; Try moving the <script> tag from <head> to the <body>.
You can simply use the Plain angular wrapper that I created:
https://github.com/khashayar/ng-plaid

No Permission error using Firebase

I am trying to add Firebase for the first time to an ionic application. I have set up my project and referenced the javascript files however when I run the application I see the error 'Error: Permission Denied'
I have not yet set up authentication in my app but, if I am understanding things properly I shouldn't need to do this while I am just testing.
My index.html contains the following:
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.2.0/angularfire.min.js"></script>
While the app.js has the following lines:
angular.module('starter', ['ionic', 'firebase'])
.factory("Items", function($firebaseArray) {
var itemsRef = new Firebase("https://todo-83e58.firebaseio.com/items");
return $firebaseArray(itemsRef);
})
.controller('ListCtrl', function($scope, $ionicListDelegate, Items) {
$scope.items = Items;
$scope.addItem = function () {
var name = prompt("what do you need to buy?");
if (name) {
$scope.items.$add({"name": name});
}
};
I would be grateful for any pointers on how to get the basics right as I have tried following the information on the Firebase site and I seem to have it all set up correctly. Am I misunderstanding the authentication or shouldI be able to write to the database without setting this up first ?
It sounds that your Security & Rules isn't giving you access to items. Please make sure to spend some time reading the S&R documentation.
If you are only testing the application and don't want to care about it now just set it to full read and write.
On the new console go to Database > Rules.
{
"rules": {
".read": true,
".write": true
}
}

Build an Ionic App with Wistia Player API not working on iOs.

So I am building an Ionic / AngularJS app using Wistia player API. I finial tried and everything work right on browser test mode. But when compile onto iOs, it just show white screen. Here is the detail:
View - HTML page:
<!-- Wistia Embed -->
<div id="{{ 'wistia_' + mediaHashId }}" class="wistia_embed" style="width:398px;height:224px;" ng-if="mediaHashId"></div>
Controller:
$timeout(function() {
var wistiaEmbed = Wistia.embed($scope.mediaHashId, {
videoFoam: true,
playerColor: "3B97D3"
});
wistiaEmbed.bind("end", function () {
alert ("Video is finished");
});
}, 100);
So it load perfectly onto Chrome.
But when I compile it onto xcode and run it on my phone. It just show a white screen (with no JS error!)
SECOND OPTION: iframe - since iframe load okay on iOs (http://wistia.com/doc/player-api#using_iframes_and_the_player_api).
The second option is attach wistiaApi onto an iframe. But the code does not work.
View - HTML page:
<div class="video-container">
<iframe id="wistia_player" ng-src="{{ mediaHashId | wistiaEmbedUrl }}" allowtransparency="true" frameborder="0" scrolling="no" class="wistia_embed" name="wistia_embed" width="640" height="360"></iframe>
</div>
Controller:
$timeout(function() {
var wistiaEmbed = document.getElementById("wistia_player").wistiaApi;
console.log (wistiaEmbed);
wistiaEmbed.bind("end", function () {
alert ("Video is finished");
});
}, 100);
The wistiaEmbed console log an undefined.
And error log:
TypeError: Cannot read property 'bind' of undefined
at lesson-detail-ctrl.js:46
at ionic.bundle.js:24922
at completeOutstandingRequest (ionic.bundle.js:13604)
at ionic.bundle.js:13984
So clearly .wistiaApi does not work...
I do include this in my index.html:
I will love a AngularJS library like this https://github.com/brandly/angular-youtube-embed with Wistia Player...but no luck...
Wow, I've found the problem. This is actually a very common problem when building ionic apps on iOs and/or Android. When you include <script> tags in your index.html, always put the full http://.... instead of using just //.
In my case, I included the Wistia API via their official documentation like:
<script src="//fast.wistia.com/assets/external/E-v1.js"></script>
It works on browsers because browsers are smart. Devices are not as smart as browsers so by including the http like so:
<script src="https://fast.wistia.com/assets/external/E-v1.js"></script>
Solves it!

Using ngCordova plugins without calling them in app.js?

My app is looking good, thanks to Ionic. All the core info is there and I'm just adding the frills - email, sharing, media (one of the functions is a metronome) and so on.
I can't get any plugins to work.
I've had success with a previous Ionic app but the plugins were all called from within
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
}
}
and indeed the Statusbar plugin seems to working fine and it is called from within there.
I'm using the Side Menu starter with tabs built in btw.
My issue, I suppose, is that I've three controller files.
main_ctrls.js - for the main app
menu_ctrls.js - for the menu pages like feedback and email, analytics
extras_ctrls.js - for the "extra" section with the metronome and so on.
I've put 'ngCordova' as a dependency in each module and called the plugin from within the controller with the ready function. Here is the email controller.
angular.module('menu.controllers', ['ngCordova'])
.controller('FeedCtrl', function($ionicPlatform, $scope, $cordovaEmailComposer) {
$ionicPlatform.ready(function() {
$cordovaEmailComposer.isAvailable().then(function() {
// is available
alert('Email is available');
}, function () {
// not available
alert('Email is NOT available');
});
var email = {
to: 'max#mustermann.de',
cc: 'erika#mustermann.de',
bcc: ['john#doe.com', 'jane#doe.com'],
attachments: [
'file://img/logo.png',
'res://icon.png',
'base64:icon.png//iVBORw0KGgoAAAANSUhEUg...',
'file://README.pdf'
],
subject: 'Cordova Icons',
body: 'How are you? Nice greetings from Leipzig',
isHtml: true
};
$cordovaEmailComposer.open(email).then(null, function () {
alert('Email discarded.');
});
})
});
I'm testing it on Android (Nexus 4 with Android 5.1) with Chrome inspect and I just get an error saying "Cannot read property 'isAvailable' of undefined". Needless to say, the alerts don't pop up.
This happens with all plugins called from within controllers in this way.
What am I doing wrong?
It seems like you are invoking the plugins before the cordova device ready is fired. In my angularjs application I have done the following.
1. Removed ng-app from html and did manual bootstrap through script
2. Added cordova.js file to the dependency. ( As the last dependency. After ng-cordova js)
3. Placed the cordova.js in the same folder as that of the index.html. (No explanation for why. From any other location, simply it was not getting added. May be something specific pertaining to cordova.)
4. Added the following script to the index.html
<script type="text/javascript" language="text/javascript">
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
onDeviceReady = function() {
alert("hello!");
angular.element(document).ready(function() {
angular.bootstrap(document, ["main"]);
});
};
</script>
Here "main" is my main angularjs module. This ensures that the app is loaded only after the device ready event is fired by cordova and all cordova related functions are available. Specific to ionic I donot have anycode. May be the portion where ionic bootstraps the app can be put instead of angular.bootstrap.
My assumptions: you have added the plugins to your cordova project through the command
cordova plugin add <plugin-location>
index.html ng-cordova include are okay if you can use ngCrdova plugins in app.js, I think ng-cordova is bad injected across angular dependencies. Try this:
app.js
controllers.js
adding ng-cordova to project involves adjusting the module definition files like:
app.js
angular.module('startapp', ['ionic','ngCordova','startapp.controllers'])
controllers.js
angular.module('startapp.controllers', [])
.controller('AppCtrl', function($scope,$cordovaEmailComposer) {
var email = {
to: 'max#mustermann.de',
cc: 'erika#mustermann.de',
bcc: ['john#doe.com', 'jane#doe.com'],
attachments: [
'file://img/logo.png',
'res://icon.png',
'base64:icon.png//iVBORw0KGgoAAAANSUhEUg...',
'file://README.pdf'
],
subject: 'Cordova Icons',
body: 'How are you? Nice greetings from Leipzig',
isHtml: true
};
$cordovaEmailComposer.open(email).then(null, function () {
// user cancelled email
});
})
Only include ngCordova in app.js app definition.

Resources