Reputation: 386
I have an Ionic app that allows users to auth with Instagram, Facebook, and Twitter. You can link other accounts that aren't your primary login as well. The problem I'm running into is making calls to the Instagram API in my controller so I can display the profile image for the associated Instagram account. Facebook and Twitter offer a designated URL to do this so I don't need to make a GET request and I don't run into this issue.
I am using Auth0 and I am broadcasting changes to the Auth0 user profile to make sure auth credentials are current throughout the app.
.service('auth', function ($rootScope) {
var self = this;
self.profile = 'OldProfile';
self.setProfile = function (newVal) {
self.profile = newVal;
$rootScope.$broadcast('newProfile', newVal);
}
});
and in my controller:
$scope.profile = auth.profile;
$rootScope.$on('newProfile', function (e, data) {
$scope.profile = data;
});
$scope.changeProfile = function () {
auth.setProfile('NewProfile');
}
The problem I'm encountering is I need to grab user credentials from the Auth0 profile to construct the Instagram $http.get request for that particular user, then get the URL for the user profile image.
$scope.facebook = [];
$scope.twitter = [];
$scope.instagram = [];
$scope.facebookCheck = function() {
for (i = 0; i < $scope.profile.identities.length; i++) {
if (angular.equals($scope.profile.identities[i].provider, "facebook")) {
if ( i == 0) {
$scope.facebook.name = $scope.profile.name;
$scope.facebook.photo = "http://graph.facebook.com/" + $scope.profile.user_id + "/picture?type=large";
} else {
$scope.facebook.name = $scope.profile.identities[i].profileData.name;
$scope.facebook.photo = "http://graph.facebook.com/" + $scope.profile.identities[i].user_id + "/picture?type=large";
}
return true;
}
}
return false;
};
$scope.twitterCheck = function() {
for (i = 0; i < $scope.profile.identities.length; i++) {
if (angular.equals($scope.profile.identities[i].provider, "twitter")) {
if ( i == 0) {
$scope.twitter.name = "@" + $scope.profile.screen_name;
$scope.twitter.photo = "https://twitter.com/" + $scope.profile.screen_name + "/profile_image?size=normal";
} else {
$scope.twitter.name = "@" + $scope.profile.identities[i].profileData.screen_name;
$scope.twitter.photo = "https://twitter.com/" + $scope.profile.identities[i].profileData.screen_name + "/profile_image?size=normal";
}
return true;
}
}
return false;
};
$scope.instagramCheck = function() {
for (i = 0; i < $scope.profile.identities.length; i++) {
if (angular.equals($scope.profile.identities[i].provider, "instagram")) {
if ( i == 0) {
$scope.instagram.name = "@" + $scope.profile.nickname;
$http.jsonp("https://api.instagram.com/v1/users/"+ $scope.profile.user_id +"/?access_token="+ $scope.profile.access_token).success(
function(data, status) {
$scope.instagram.photo = data.data.profile_picture;
}
);
} else {
$scope.instagram.name = "@" + $scope.profile.identities[i].profileData.nickname;
$http.jsonp("https://api.instagram.com/v1/users/"+ $scope.profile.identities[i].user_id +"/?access_token="+ $scope.profile.identities[i].access_token).success(
function(data, status) {
$scope.instagram.photo = data.data.profile_picture;
}
);
}
return true;
}
}
return false;
};
The if-else is due to the way Auth0 stores user data. If the user first logs in with the provider (Instagram in this case), it will be identity 0 and the JSON tree is a little skewed as such. I know I can't make the $http.get request in this manner, but I'm not sure how to get around doing it. I'm new to Angular and I'm having trouble grasping how to get around this problem. I have looked through tons of questions and blog posts about similar problems, but can't figure it out. Here is the view in question as well,
<ion-view title="Account">
<ion-content class="has-header padding">
<div class="list item-shadow">
<ion-item class="item item-light item-avatar" ng-if="facebookCheck() == true">
<img ng-src={{facebook.photo}}>
<h2><i class="icon icon-color-fb ion-social-facebook"></i> {{facebook.name}}</h2>
<p>Your Facebook account is linked</p>
</ion-item >
<ion-item class="item item-light item-avatar" ng-if="twitterCheck() == true">
<img ng-src={{twitter.photo}}>
<h2><i class="icon icon-color-twitter ion-social-twitter"></i> {{twitter.name}}</h2>
<p>Your Twitter account is linked</p>
</ion-item >
<ion-item class="item item-light item-avatar" ng-if="instagramCheck() == true">
<img ng-src={{instagram.photo}}>
<h2><i class="icon icon-color-insta ion-social-instagram"></i> {{instagram.name}}</h2>
<p>Your Instagram account is linked</p>
</ion-item>
</div>
<button class="button button-block button-positive icon-left icon ion-social-facebook" ng-if="facebookCheck() == false" ng-click="linkFacebook()"> Add Facebook Account</button>
<button class="button button-block button-calm icon-left icon ion-social-twitter" ng-if="twitterCheck() == false" ng-click="linkTwitter()"> Add Twitter Account</button>
<button class="button button-block button-dark icon-left icon ion-social-instagram" ng-if="instagramCheck() == false" ng-click="linkInstagram()"> Add Instagram Account</button>
<br>
<button class="button button-assertive button-block" ng-click="logout()">Logout</button>
</ion-content>
</ion-view>
Any help/guidance is appreciated.
Upvotes: 0
Views: 175
Reputation: 8096
In you html you are doing checks at runtime-
ng-if="facebookCheck() === true"
The issue probably is that the facebook check is also updating the scope.
$scope.facebook.name = $scope.profile.name;
This should kick off another digest to update the view with the new values. Once that digest kicks off, the checks are done again, etc etc.
When the profile is loaded, set $scope.facebook.name
there. Additionally, have another set a vars like, isFacebook
, isInstagram
, etc. And update your view to this- ng-if="isFacebook"
.
The short and skinny: You're kicking off a digest with your check everytime a digest occurs. This is your infinite loop.
Upvotes: 1