I'm building an app with an Express/Node backend and Angular JS for the front end. Kinda new to using this stack and I'm having a hard time receiving the data in an Angular Service + Controller
Backend: Users can authenticate with Facebook using Passport JS that attaches a users object to every request. I opened up an endpoint that checks if req.user exists, like so:
app.get('/checklogin', function(req,res,next){
if(req.user){
console.log("we found a user!!!");
console.log("name:" + req.user.displayName);
console.log("user id" + req.user.id);
return res.status(201).json(req.user);
} else {
console.log("there is no user logged in");
}
});
If the req.user exists, so the user is authenticated, it sends a JSON response.
What I'm trying to do is in Angular is sending a http.get to this /checklogin endpoint and handle the response. I want to bind to the scope if the user is authenticated (req.user exists or not), and if so bind displayName and Id as well, and hide show nav links and pages.
But my setup in Angular hits the API endpoint but doesnt seem to receive any data????:
.service("Login", function($http){
this.isLoggedIn = function(){
return $http.get("/checklogin")
.then(function(response){
console.log(response)
return response;
}, function(response){
console.log("failed to check login");
});
};
})
.controller("mainController", function($scope, Login){
Login.isLoggedIn()
.then(function(doc){
console.log(doc);
console.log(doc.data);
}, function(response){
alert(response);
});
})
the console.log(doc) and console.log(doc.data) don't log anything...... What am I doing wrong here?????
More info: the mainController is loaded in the index.html file:
<html lang="en" ng-app="myApp" ng-controller="mainController">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--load jQuery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<!--load Bootstrap JS-->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<!--load Angular JS-->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-route.js"></script>
<!--latest compiled and minified Bootstap CSS-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!--link custom CSS file-->
<link rel="stylesheet" type="text/css" href="/css/style.css">
<script src="/js/app.js"></script>
</head>
<body>
<!-- NAVBAR ================== ---->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="nav-header">
<a class="navbar-brand" href="#/">Votely</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>Sign in with Facebook</li>
<li>Sign Out</li>
</ul>
</div>
</div>
</nav>
<!-- Dynamically render templates Angular JS -->
<div class="container" ng-view>
</div>
</body>
Any help much appreciated, thanks!
You should return a promise from service if you are using then inside controller i.e.
.service("Login", function($http){
this.isLoggedIn = function(){
return $http.get("/checklogin");
};
.isLoggedIn function in your service should looks like this:
this.isLoggedIn = function(){
return $http.get("/checklogin");
}
thanks, I got it working now. I was using the browser in Cloud 9 IDE and the server was sending a 503 response, not sure why. It works now in Chrome and Firefox etc. after I set the service to return a promise!
Related
Hello I'm trying to implement "login with twitter", but it wont work on live website.
I followed this tutorial but it wont work on my implementation.
When I run it via MAMP the OAuth wont pop, but when I preview from PHPSTORM it pop and the login will work.
I added a "console.log" to log the final OAuth response and nothing happens while running the website via MAMP (live server), only via PHPstorm.
Can someone tell me what I'm doing wrong please?
$(document).ready(function(){
//function stops doubleclicks
$('#twitter-button-loggin').on('click', function() {
console.log("clicked")
const userLoginTwitter = {}
// Initialize with your OAuth.io app public key
OAuth.initialize('HwAr2OtSxRgEEnO2-JnYjsuA3tc');
// Use popup for OAuth
OAuth.popup('twitter').then(twitter => {
// console.log('twitter:', twitter);
userLoginTwitter.twitter = twitter
// Prompts 'welcome' message with User's email on successful login
// #me() is a convenient method to retrieve user data without requiring you
// to know which OAuth provider url to call
twitter.me().then(data => {
userLoginTwitter.me = data
// console.log('data:', data);
//alert('Twitter says your email is:' + data.email + ".\nView browser 'Console Log' for more details");
});
// Retrieves user data from OAuth provider by using #get() and
// OAuth provider url
twitter.get('/1.1/account/verify_credentials.json?include_email=true').then(data => {
// console.log('self data:', data);
userLoginTwitter.SelfData = data
})
console.log(userLoginTwitter)
});
})
<!DOCTYPE html>
<html lang="pt-br">
<head>
<title>Vais Gostar </title>
<meta charset="utf-8">
<link rel="stylesheet" href="style/base.css">
<script type="text/javascript" src="https://cdn.rawgit.com/oauth-io/oauth-js/c5af4519/dist/oauth.js"></script>
<script type="text/javascript" src="js/jquery-3.6.0.min.js"> </script>
<script type="text/javascript" src="js/anime.js"></script>
<script type="text/javascript" src="js/base.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/4.12.0/bootstrap-social.min.css">
</head>
<body >
<a id="twitter-button-loggin" class="btn btn-block btn-social btn-twitter">
<i class="fa fa-twitter"></i> Sign in with Twitter
</a>
<a id="twitter-button-loggin" class="btn btn-danger">
<i class="fa fa-twitter"></i> Log Out
</a>
</body>
</html>
I am new to Angularjs. I am trying to build a simple system with a login page and it will redirect to another page after successfully logged in.
I am trying to show all the pages in index.html with ng-view (including login page). I try to use ng-if to decide when to show the navigation bar on top of the page.
The value of vm.page will not change after logged in
index.html
<html ng-app="myApp">
<head>
<title></title>
<link href="css/bootstrap.min.css" rel="stylesheet"/>
<link href="css/custom.css" rel="stylesheet"/>
<script src="jquery/jquery-3.3.1.min.js"></script>
<script src="node_module/angular/angular.js"></script>
<script src="node_module/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="controllers/login-controller.js"></script>
</head>
<body>
<div ng-controller="LoginController as lg" >
<div ng-if="lg.page != 'Login'" ng-include="'view/navigation-top.html'"></div>
</div>
<div ng-view></div>
</body>
login-controller.js
angular.module('myApp').controller("LoginController", LoginController);
function LoginController($http, $location, $scope) {
var vm = this;
vm.page = "Login";
vm.login = function(){
vm.page = "Main";
$location.path('/')
}
}
It is working when the vm.page is initiate and set to "Login", but the page does not change when i set it to "Main".
Appretiate if anyone can help me, thank you :D
The problem is the $location.path('/') call in your Login-Function. This will navigate to /index.html and re-initialize the LoginController. Therefore the vm.page variable is reset to 'Login'.
Remove the location.path() or create a service which reatains the Page/Login-State.
When I call a get request, I am getting the ngRepeat:Dupes error because what my get request is getting me from a console.log shows me the hard-coded html code from the page itself.
Here is the console.log
mainController.js:10 <!DOCTYPE>
<html ng-app="myApp">
<head>
<title>Social Network Tutorial</title>
<link rel="stylesheet" href="libs/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" href="libs/bootstrap/css/bootstrap-theme.min.css"/>
<link rel="stylesheet" href="css/stylesheet.css"/>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" ng-controller="navigationController">
<div class="container">
<div ng-show="!loggedIn">
<input type="text" ng-model="login.email">
<input type="password" ng-model="login.password">
<button ng-click="logUserIn()">Login</button>
<a ui-sref="signUp">Create An Account</a>
</div>
<div ng-show="loggedIn">
<a ui-sref="editProfile">Edit Profile</a>
<a ng-click="logOut()">Logout</a>
</div>
</div>
</nav>
<div ui-view></div>
<!--Libraries-->
<script type="text/javascript" src="libs/angular/angular.min.js"></script>
<script type="text/javascript" src="libs/angular-ui-router/angular-ui-router.min.js"></script>
<script type="text/javascript" src="libs/ng-file-upload/ng-file-upload.min.js"></script>
<script type="text/javascript" src="app.js"></script>
<!--Controllers-->
<script type="text/javascript" src="partials/signup/signupController.js"></script>
<script type="text/javascript" src="partials/navigation/navigationController.js"></script>
<script type="text/javascript" src="partials/profile/editProfileController.js"></script>
<script type="text/javascript" src="partials/main/mainController.js"></script>
</body>
</html>
My client side controller shows the following code:
var getTweets = function(initial){
$http.get('/tweets').then(function(response){
if(initial){
$scope.tweets = response.data;
} else {
$scope.incomingTweets = response.data;
};
});
};
getTweets(true);
and my server side api function is the following:
router.get('/tweets', tweetController.getTweets);
lastly the server side controller is the following:
module.exports.getTweets = function(req,res){
console.log("works");
Tweet.find({}).sort({date: -1}).exec(function(err, data){
if(err) {
throw err;
res.json({status: 500});
} else {
console.log(data);
res.json(data);
};
});
};
What did I do wrong?
The console.log on the server side doesn't show "works" meaning the request didn't even reach the server but for some reason the client side got a response.
The server probably returned an error page. Inspect the html that was returned to see what's going on, it probably contains some information.
Debug your app by executing the url /tweets in the browser or Postman (or use Chrome dev tools). If the server doesn't return json, either the url is wrong or something is wrong server side. That eliminates a bug in the client side.
I am trying to load templates in angular but get an error:
Failed to load resource: net::ERR_FILE_NOT_FOUND angular.js:102 Error:
[$compile:tpload]
http://errors.angularjs.org/1.3.15/$compile/tpload?p0=pages%2Fhome.html
at Error (native)
at file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:6:417
at file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:137:25
at file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:112:113
at n.$eval (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:126:15)
at n.$digest (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:123:106)
at n.$apply (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:126:293)
at l (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:81:240)
at M (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:85:342)
at XMLHttpRequest.e (file:///C:/Users/Abu-Mustaqiima/Documents/AngularJS/WeatherApp/Video1/Starter/angular.js:86:418)
Here's my index.html
<!DOCTYPE html>
<html lang="en-us" ng-app="weatherApp">
<head>
<title>AngularJS Weather Forecast SPA</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta charset="UTF-8">
<!-- load bootstrap and fontawesome via CDN -->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<style>
html, body, input, select, textarea
{
font-size: 1.05em !important;
}
</style>
<!-- load angular via CDN -->
<script src="http://code.angularjs.org/1.3.0-rc.2/angular.min.js"></script>
<script src="http://code.angularjs.org/1.3.0-rc.2/angular-route.min.js"></script>
<script src="http://code.angularjs.org/1.3.0-rc.2/angular-resource.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">AngularJS Weather</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-home"></i> Home</li>
</ul>
</div>
</nav>
</header>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
// MODULE
var weatherApp = angular.module('weatherApp', ['ngRoute', 'ngResource']);
// ROUTES
weatherApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.htm',
controller: 'homeController'
})
.when('/forecast', {
templateUrl: 'pages/forecast.htm',
controller: 'forecastController'
})
});
// CONTROLLERS
weatherApp.controller('homeController', ['$scope', function($scope) {
}]);
weatherApp.controller('forecastController', ['$scope', function($scope) {
}]);
I tried to use WAMP server to load the pages from, but still get the same error.
Currently your template protocol contains file:// which would not accessible through your browser.
You need to host your code on some server(like IIS, WAMP, etc.) & paste your whole code directory on the server, in order to work your code. Other wise your code looks fine.
So the URL should be either http:// or https:// then your template will fetch from server directly.
Use https or http in URL .Example:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
I'm building a sample application with YouTube API (v3), that would provide a list of videos based on a search term. The concept is to populate the page using the data from the response.
I have used the client library documented in v3 to access the API, and send my request, however I don't know how to properly navigate through the data provided in the response in order to display the desired elements. The code below shows my script, where I am trying to access and list the title of the videos in the response:
$(function () {
//FUNCTION TO COLLECT QUERY TERM FROM SEARCH FORM
var $searchField = $('#search-text');
$('#mainSearch'). on ('submit', function(e){
e.preventDefault();
if ($searchField.val() !== '') { //IF SEARCH FORM IS NOT EMPTY
var $searchQuery = $searchField.val()+ ' parody'; //PREPARE SEARCH QUERY
makeRequest($searchQuery); //PASS SEARCH QUERY TO REQUEST FUNCTION
}
else {
$searchField.focus(); //ADD ERROR CLASS HERE
$searchField.blur(function (e){
//REMOVE ERROR CLASS HERE
});
}
});
function makeRequest(query){
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: query
});
$('.content').empty();
request.execute(parseResponse);
}
function parseResponse(data) {
$.each(data, function (i, items){
var $infoDiv = $('<div></div>');
$infoDiv.append('<p>'+ items.snippet.title +'</p>');
$('.content').append($infoDiv);
});
}
});
//LOAD API CLIENT
function initClient() {
gapi.client.load('youtube', 'v3');
gapi.client.setApiKey('AIzaSyARVmOp3tBIA3ZgW6z4DK_-1sMJwulPvps');
}
However my page does get not populated with any data, and I get this error in my console:
Uncaught TypeError: Cannot read property 'title' of undefined
And here is the markup for my page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Parrdy Template</title>
<!--
<Bootstrap></Bootstrap>-->
<link href="stylesheets/bootstrap.min.css" rel="stylesheet"/>
<link href="stylesheets/style.min.css" rel="stylesheet"/>
<!--
<HTML5>Shim and Respond.js IE8 support of HTML5 elements and media queries </HTML5>--><!--
<WARNING>
<Respond class="js">doesn't work if you view the page via file:// </Respond>
</WARNING>--><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<div class="container">
<div class="header">
<img src="/images/Logo1_mod.png" width="200">
<form role="form" id= "mainSearch" class="navbar-form navbar-right pull-right">
<div class="form-group">
<input type="text" id="search-text" placeholder="Search" class="form-control">
</div>
<button type="submit" id="vid-search" class="btn btn-sm btn-warning">Search</button>
</form>
</div>
{{{body}}}
<div class="footer">
<ul class="nav nav-pills pull-left">
<li><a class="customcolor" href="#">About</a></li>
<li><a class="customcolor" href="#">Contact Us</a></li>
</ul>
</div>
</div><!--container ends-->
<!--
<jQuery>(necessary for Bootstrap's JavaScript plugins) </jQuery>-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><!--
<Include>all compiled plugins (below), or include individual files as needed</Include>-->
<script src="js/bootstrap.min.js"></script>
<script src="js/core1.1.js"></script>
<script src="https://apis.google.com/js/client.js?onload=initClient" type="text/javascript">
</script>
</body>
</html>
Any help on how to access the elements correctly from a YouTube API response would be appreciated. Thanks.
The first thing you'll want to keep in mind is that the stuff you are after is nested in the response as data so you need to access 'response.data' and within that data is an array of items. You'll want to access the first array with items[0] now you can grab the id from here or go deeper with .snippet or .statistic
get(url)
.then(response => {
id: response.DATA.items[0].id
title: response.DATA.items[0].snippet.title
}
.catch(
error => {console.log(error)}
You should change your loop like this:
$.each(data.videos, function (i, items){
var $infoDiv = $('<div></div>');
$infoDiv.append('<p>'+ items.snippet.title +'</p>');
$('.content').append($infoDiv);
});