AngularJS Ajax get issue - ajax

I am a bit new to angular and am scratching my head over this one. my factory console.log's show that the first time through everything is defined correctly, but the factory is for some reason re-evaluating the data I pass it to undefined. Here is my code starting with the html input that is passing the data to the controller then to the factory:
HTML:
<input type="text" placeholder="Enter Channel" ng-model="channel" ng-keydown="$event.which === 13 && cname(channel)"/>
This will send to my controller what is typed in the input field once the enter key is pressed cnam(channel)
Controller and Factory:
angular.module('youtubePlaylistAppApp')
.factory('ytVids', function($http){
return{
getChannel: function(name){
console.log('name: '+name);
var url = 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername='+ name +'&key=[my api key]';
console.log(url);
return $http.get(url);
},
getVids: function(channel){
console.log('channel: '+ channel);
return $http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&maxResults=50&playlistId='+channel+'&key=[my api key]')
.success(function(response){
//console.log(response.items);
return response.items;
});
}
};
})
.controller('indexCtrl', function ($scope, ytVids) {
$scope.cname = function(channel){
console.log(channel);
ytVids.getChannel(channel);
ytVids.getChannel().success(function(response){
console.log(response);
console.log(response.items[0].contentDetails.relatedPlaylists.uploads);
ytVids.getVids(response.items[0].contentDetails.relatedPlaylists.uploads)
.success(function(data){
console.log(data.items);
$scope.ytChannel = data.items;
});
});
};
});
Here is the output I am seeing in my console dev tools after enter is pressed when typing in the input field:
the first console log console.log(channel); console logs the correct response. If I type "freddiew" and press enter, that is what is logged
Then I pass that into my factory ytVids.getChannel(channel); and console log in the factory console.log('name: '+name); This logs the correct response as in name: freddiew
I then declare a variable var url = and give it the youtube url and concat the channel name with the url
I then console log the variable and get what is expected https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=freddiew&key=[my api key]'
This url works when I have tried it in postman and just hard coding a name in. but passing in the name, the console then spits out some more logs which I dont know why, and it looks like it overides the url I just built out to make the call because this is what is logged from the factory:
name: freddiew
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=freddiew&key=[my key]
It is then logged after this as undefined and the api call concats undefined with the url and makes the api call with this undefined url
name: undefined
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=undefined&key=[my key]
forUsername= is where the channel name should go.
anyone know why it is being defined as undefined?

I think you have wrong extra service call.
.controller('indexCtrl', function ($scope, ytVids) {
$scope.cname = function(channel){
console.log(channel);
//ytVids.getChannel(channel); <-- you should remove this & passed channel param in below call
ytVids.getChannel(channel).success(function(response){
console.log(response);
console.log(response.items[0].contentDetails.relatedPlaylists.uploads);
ytVids.getVids(response.items[0].contentDetails.relatedPlaylists.uploads)
.success(function(data){
console.log(data.items);
$scope.ytChannel = data.items;
});
});
};
});

Related

Window object is undefined after deploy to netlify

I want to build an email verification. After the user registers, the user gets an email and clicks on it for verification purposes. The email-link invokes a netlify lambda function (api end point). Inside the link is a jwt token, which I decode on the backend. I used
window.location.href
for it and sliced the part I needed and decoded it. On localhost, it works fine, however, if I deploy it to netlify, I get an
window is undefined
error. I read that you have to check for
typeof window !== 'undefined'
However, if I add that to my lambda function I don't get any console.log statements.
exports.handler = async (event, context, callback) => {
if (typeof window !== 'undefined') {
let url = window.location.href
let index = url.indexOf("=");
let token = url.slice(index+1)
console.log(token, 'token here')
const decoded = jwt.verify(token, process.env.SECRET);
console.log('confirm registration route triggered',decoded)
if (decoded) {
const { email } = decoded;
console.log(decoded, 'decoded here')
User.findOneAndUpdate({email: email}, {verified: true },(...e)=>{
console.log(e)
});
} else {
console.log('could not update user')
//redirect user to page with message about email confirmation link expiration
//and proposal to register again
}
console.log('confirm registration got invoked')
}
return {
statusCode: 400,
body: "Oops"
}
};
I read that the function first runs on the server when deployed and afterwards on the client. Seems like it does not run on my client, as I invoke the api-endpoint directly? I'm quite a beginner when it comes to API-Endpoints, thanks for reading!
In case you have the same issue when deploying to netlify, you have to run
event.queryStringParameters
which gives you access to the query parts of your url.

ApplePay completeMerchantValidation fails

We have a site example.com behind ssl that runs a page with ApplePay.
We've got a server side that returns a Merchant Session that looks like the following:
{"epochTimestamp":1581975586106,"expiresAt":1581979186106,"merchantSessionIdentifier":"SSH8E666B0...","nonce":"1239e567","merchantIdentifier":"...8557220BAF491419A...","domainName":"example.com","displayName":"ApplePay","signature":"...20101310f300d06096086480165030402010500308..."}
We receive this response in session.onvalidatemerchant as a string and convert it to a Json Object and pass to session.completeMerchantValidation.
As a result we get the following error:
Code: "InvalidAccessError"
Message: "The object does not support the operation or argument"
We run the following code on our page:
.....
session.onvalidatemerchant = (event) => {
const validationURL = event.validationURL;
getApplePaySession(validationURL).then(function (response) {
try {
let resp = JSON.parse(response);
session.completeMerchantValidation(resp);
} catch (e) {
console.error(JSON.stringify(e));
}
});
};
....
Additional questions:
Is the object described above a "correct" Merchant Session opaque that needs to be passed to completeMerchantValidation or it's missing some fields?
Is this object needs to be passed as is or it needs to be base64 encoded?
Does it need to be wrapped into another object?
Any help or lead is greatly appreciated.

Asynchronously populate Sammy.Storage cache

I'm having difficulty accessing requestJSON on a jQuery $.ajax object outside of the success callback. If I do:
var ajax_request = $.ajax({
dataType: 'json',
contentType: 'application/json'
});
console.log(ajax_request.responseJSON);
// this results in `undefined`
How can I access the responseJSON without adding a .success() callback? If I inspect ajax_request in Firebug, I can see the responseJSON property, and the data I expect, but I can't access it via:
ajax_request.responseJSON
More specifically, I'm building an SPA using Sammy and Knockout. In some routes, I need to be able to get JSON from cache, and if it doesn't exist, get the value from a service call and then set it into cache:
var cached_json = storage.fetch('cached_json', function() {
// make service call
return $.getJSON(url);
});
event_context.render('template.tpl', {'json': cached_json}).appendTo('#my-target');
But, of course, calling storage.fetch doesn't cause the rest of the code to pause until $.getJSON is complete. This is the part I can't quite figure out how to structure.
here's how i would implement it
responseJSON = "";
$.get("myurl.php",function(jdata){
responseJSON = jdata;
},"json");
i like to see the ajax method at a glace, but in your case you can do the same by
....
success : function(jdata){ responseJSON = jdata; }
....
PS: i believe that initializing the blank responseJSON is not required since any variable without var is in global scope, but it would help for clarity
I ended up solving this by creating a deferred object that gets or creates the value I need:
function get_or_create_cache(storage, key, service_endpoint) {
return $.Deferred(function(deferred) {
var c = storage.get(key);
if (c === null || c === undefined) {
$.when(jsonp_service_request(service_endpoint)).done(function(json) {
storage.set(key, json);
deferred.resolve(json);
});
}
else {
deferred.resolve(c);
}
}).promise();
}
In this function, storage refers to a Sammy.Storage instance. jsonp_service_request is a local function that returns a jsonp response, taking into account the location.hostname for local development, where I'm pointing to local.json files, or a remote environment, where I'm calling into an actual API. jsonp_service_request returns an $.ajax function.
Then in my Sammy route, I can do:
this.get('#/', function(event_context) {
$.when(get_or_create_cache(storage, 'my-cache-key', 'service-endpoint'))
.then(function(json) {
event_context.render('my-template.template', {'value-name': json})
.appendTo('#my-target');
});
});

Parse.User.save() doesn't work with Facebook API

I'm using the Facebook SDK to auth a user, and trying to save the user's email to the record after authenticating. However, I keep getting an error on the save call.
The code in question:
Parse.FacebookUtils.logIn({
access_token: authResponse.access_token,
expiration_date: expire_date.toISOString(),
id: response.id
},
{
success: function(user) {
console.log("success!");
user.set({"email":response.email});
user.save();
window.App.navigate("#myplaces", {trigger:true});
},
...
That user.save() call returns error occurred: http://www.parsecdn.com/js/parse-1.1.14.min.js:1: TypeError: 'undefined' is not an object.
According to the docs, I have to be in an authentication call (".logIn", etc.) to perform save(), so I'm wondering if this still works with Parse.FacebookUtils.logIn. Seems like it should.
Ideas as to why this isn't working? The ideal behavior is to log the user in, retrieve information from the FB response, and save that back to the user record on Parse.
Thanks!
Justin
Not sure about this but I had the same problem in Cloud Code and I used success/error callbacks when calling save(...):
user.save(null, {
success: function(){
// Code
},
error: function(){
// Code
}
});
See also here: https://parse.com/questions/saving-a-relation-on-the-current-user

Error handling when downloading a file from a servlet

I have a web application that must work with IE7 (yeah i know..) where the frontend is entirely made with ExtJS4, and theres a servlet used to download files. To download a file i send some parameters so i cant simply use location.href. it must be a POST.
So far it works, but when an exception is thrown in the servlet i dont know how to handle it to show the user some alert box or some message without redirecting to another page.
In my webapp im also using DWR and im aware of the openInDownload() function, but it triggers a security warning in IE.
So, (finally!) the question is
Using this code:
post = function (url, params) {
var tempForm=document.createElement("form");
tempForm.action=url;
tempForm.method="POST";
tempForm.style.display="none";
for(var x in params) {
// ...snip boring stuff to add params
}
document.body.appendChild(tempForm);
tempForm.submit();
return tempForm;
}
is it possible to stay in the same page after submitting ?
or with this other one:
Ext.Ajax.request({
url: './descargaArchivoNivs',
method: 'POST',
autoAbort: true,
params: {
nivs: jsonData
},
success: function(response){
// HERE!!
// i know this is wrong
document.write('data:text/plain,' + response.responseText );
/* this looked promising but a warning pops up
var newwindow = window.open();
newwindow.document.open();
newwindow.document.write('data:text/plain, ' + response.responseText );
newwindow.document.close();*/
},
failure: function(resp){
alert('There was an error');
}
});
is it possible to open the file download dialog // HERE!! with the response content??
or is there some other way to open the file download dialog on success, and on failure show a friendly message without losing the users input (the params of the POST) ?
(sorry if this post was too long)

Resources