AngularJS Calling a service not working - javascript

I am trying to call a service from inside the function "onNotification(e, $scope, currentUser)" However every time I try and log it, it either comes back with the error:
processMessage failed: Error: TypeError: Cannot set property 'Current' of undefined
or if I use "var userRegistration = this.currentUser" I get "undefined" in the log, however I know that the service is being updated as it returns the correct value when I log the result outside the function.
Here's my code:
function onNotification(e, $scope, currentUser) {
var Currentuser = this.currentUser;
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log(Currentuser);
console.log("regID = " + e.regid);
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if ( e.foreground )
{
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
var my_media = new Media("/android_asset/www/"+ soundfile);
my_media.play();
}
else
{ // otherwise we were launched because the user touched a notification in the notification tray.
if ( e.coldstart )
{
$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
}
else
{
$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
}
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
Here's the Service within the same js file:
App.service('currentUser', function ()
{
return{};
});
How should I go about calling the service inside this function? My Angular knowledge is limited. Any help would be much appreciated.
Update: In response to user PSL. onNotification is called here:
App.controller('LogHomeCtrl', function($scope, $log, $state, currentUser)
{
var pushNotification;
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady()
{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if ( device.platform == 'android' || device.platform == 'Android'){
pushNotification.register(
successHandler,
errorHandler,
{
"senderID":"460885134680",
"ecb":"onNotification"
});
} else {
pushNotification.register(
tokenHandler,
errorHandler,
{
"badge":"true",
"sound":"true",
"alert":"true",
"ecb":"onNotificationAPN"
});
}
}
function successHandler (result)
{
alert('result = ' + result);
}
function errorHandler (error)
{
alert('error = ' + error);
}
});

Try Changing
var Currentuser = this.currentUser;
to
var Currentuser = currentUser;
currentUser does not belong to onNotification it is meerly being passed in as a parameter and therefore being defined as a variable in its local scope. But not as a property of itself
Edit
onNotification ought to be defined inside a controller. eg
yourModuleName.controller('controllerName', ['$scope', 'currentUser', function($scope, currentUser) {
$scope.currentUser = currentUser;
$scope.onNotification = function(e, $scope, $scope.currentUser) {
}
}]);

Related

Controller --- Factory: passing parameters

I have this function in my controller :
$scope.goToPath = function ( path, pid ) {
$scope.pid = pid;
console.log("scope pid : " + $scope.pid);
$scope.edit = true;
$state.go(path);
};
then i'm calling this function to get a promise from my factory :
$scope.getProjectById = function () {
projectFactory.getProject($scope.pid)
.success(function (data) {
if(data == null){
$scope.errorMessage = "Le projet avec l'id : " + pid + " n'existe pas";
}else {
$scope.project = data;
}
})
.error(function (data, status, headers, config) {
$scope.errorMessage = "Erreur : " + data.error + ' ' + status;
})
};
And my Factory looks like this :
factory.getProject = function (projectId) {
console.log('Project Id factory : '+projectId);
return $http.get('http://localhost:8080/gestionprojet/Project/' + projectId)
};
return factory;
but the variable here projectId is null, now I've checked as your see with console.log() and the pid in my controller has a value but in the factory it's equal to null.
In my view I'm calling it like :
ng-init="getProjectById()"
Any help would be appreciated. Thank you
With this scenario,your current scope is getting destroyed and new scope is getting creates.So,pid assigned to scope is also getting destroyed.
You can do like this one.
In function $scope.goToPath,
$scope.goToPath = function(path, pid ){
....
$state.go(path,{project_id:pid })
}
And in the target controller where your view is getting landed,
access it using $stateParams by injecting it.
You can refer here angular-ui routing

Parse.com / Javascript - Save users objectid string as user pointer

How do I save a user pointer to an object when i have the object id of the user.
I am able to save the object to the class in Parse but the assignee is always 'Undefined' in Parse.
e.g. I have retrieved the user object and can get the username / object id etc through:
function getUserFromUsername(username) {
Parse.initialize("...", "...");
console.log('The username passed in is: ' + username);
var User = Parse.Object.extend("_User");
var query = new Parse.Query(User);
query.equalTo("username", username);
query.first({
success : function(result) {
// Do something with the returned Parse.Object values
var userPointer = new Parse.User();
userPointer = result;
console.log(userPointer.get('username')); // this returns the correct username
return userPointer;
},
error : function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
Which is called from my save task function below: (Note, I've logged all relevant fields and they return as expected.
function saveNewTask(clientName, taskTitle, taskDue, assigneeArray) {
Parse.initialize("...", "...");
var x;
for (x in assigneeArray) {
var Task = Parse.Object.extend("Tasks");
var task = new Task();
task.set("title", taskTitle);
task.set("date", taskDue);
var thisAssignee = GetUserFromUsername(assigneeArray[x]);
task.set('assignee', thisAssignee);
task.save(null, {
success : function(task) {
// Execute any logic that should take place after the object is saved.
console.log('New object created with objectId: ' + task.id);
},
error : function(gameScore, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and message.
console.log('Failed to create new object, with error code: ' + error.message);
}
});
}
}
So you should save a pointer to the user to the task.
var Task = Parse.Object.extend("Tasks");
var task = new Task();
task.set("user", user);
task.set("title", "taskTitle");
task.set("date", taskDue);
task.save(null, {
success : function(task) {
// Execute any logic that should take place after the object is saved.
console.log('New object created with objectId: ' + task.id);
},
error : function(gameScore, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and message.
console.log('Failed to create new object, with error code: ' + error.message);
}
});
By default, when fetching an object, related Parse.Objects are not fetched. These objects' values cannot be retrieved until they have been fetched like so:
var user = task.get("user");
user.fetch({
success: function(user) {
//fetch user is here
}
});
This is explained here: https://parse.com/docs/js_guide#objects-pointers
The problem with your script is when you are querying in Parse it is done asynchronously so you can't return the user immediately. Instead you need to return the promise and then handle it when you call getUserFromUsername:
function getUserFromUsername(username) {
var User = Parse.Object.extend("_User");
var query = new Parse.Query(User);
query.equalTo("username", username);
return query.first();
}
getUserFromUsername('testUsername').then(function(result) {
//use User here
}, function(error) {
alert("Error: " + error.code + " " + error.message);
});
Take a look at this document on promise chaining for more information about promises:

JS Global Variable in AngularJS returns undefined

I'm trying to access a value inside some Javascript to use in an AngularJS service. I have stored the value inside a variable successfully but I am having issues getting that variable into my AngularJS service. Here is my code:
JS function:
function onNotification(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
var regid = e.regid
console.log(regid);
}
break;
The variable regid is what I am trying to access.
AngularJS Service:
App.service('regID', function()
{
return{}
});
Angular Function:
App.controller('MainCtrl', function($scope, $state, regID, $window){
console.log('MainCtrl');
var pushNotification;
document.addEventListener("deviceready", onDeviceReady, false);
$scope.regID = regID;
$scope.regID.regID = $window.regid;
console.log($scope.regID);
function onDeviceReady()
{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if ( device.platform == 'android' || device.platform == 'Android'){
pushNotification.register(
successHandler,
errorHandler,
{
"senderID":"460885134680",
"ecb":"onNotification",
});
} else {
pushNotification.register(
tokenHandler,
errorHandler,
{
"badge":"true",
"sound":"true",
"alert":"true",
"ecb":"onNotificationAPN"
});
}
}
function successHandler (result, $scope, regID, $window)
{
alert('result = ' + result);
}
function errorHandler (error)
{
alert('error = ' + error);
}
});
Every time I run this $window.regid comes back as undefined. Any ideas as to why?
So you have not assigned it to a global variable. You have assigned it to a local function scope variable.
To assign it to a global variable use window.regID rather than var regID.
Your regID service does nothing. It should return $window.regID.
This all being said, this is not the right approach. The correct approach would be a service that returns a promise. The service also listen to native javascript or jqlite events, and resolve the promise when the event is handled.

Retrieved anchors list gets corrupted?

I am trying to analyze anchor links ( their text property ) in PhantomJS.
The retrieval happens here:
var list = page.evaluate(function() {
return document.getElementsByTagName('a');
});
this will return an object with a property length which is good (the same length I get when running document.getElementsByTagName('a'); in the console). But the vast majority of the elements in the object have the value of null which is not good.. I have no idea why this is happening.
I have been playing with converting to a real array thru slice which did no good. I have tried different sites, no difference. I have dumped the .png file to verify proper loading and the site is properly loaded.
This is obviously not the full script, but a minimal script that shows the problem on a well known public site ;)
How can I retrieve the full list of anchors from the loaded page ?
var page = require('webpage').create();
page.onError = function(msg, trace)
{ //Error handling mantra
var msgStack = ['PAGE ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
});
}
console.error(msgStack.join('\n'));
};
phantom.onError = function(msg, trace)
{ //Error handling mantra
var msgStack = ['PHANTOM ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
});
}
console.error(msgStack.join('\n'));
phantom.exit(1);
};
function start( url )
{
page.open( url , function (status)
{
console.log( 'Loaded' , url , ': ' , status );
if( status != 'success' )
phantom.exit( 0 );
page.render( 'login.png');
var list = page.evaluate(function() {
return document.getElementsByTagName('a');
});
console.log( 'List length: ' , list.length );
for( var i = 0 ; i < list.length ; i++ )
{
if( !list[i] )
{
console.log( i , typeof list[i] , list[i] === null , list[i] === undefined );
//list[i] === null -> true for the problematic anchors
continue;
}
console.log( i, list[i].innerText , ',' , list[i].text /*, JSON.stringify( list[i] ) */ );
}
//Exit with grace
phantom.exit( 0 );
});
}
start( 'http://data.stackexchange.com/' );
//start( 'http://data.stackexchange.com/account/login?returnurl=/' );
The current version of phantomjs permits only primitive types (boolean, string, number, [] and {}) to pass to and from the page context. So essentially all functions will be stripped and that is what DOM elements are. t.niese found the quote from the docs:
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
You need to do a part of the work inside of the page context. If you want the innerText property of every node, then you need to map it to a primitive type first:
var list = page.evaluate(function() {
return Array.prototype.map.call(document.getElementsByTagName('a'), function(a){
return a.innerText;
});
});
console.log(list[0]); // innerText
You can of course map multiple properties at the same time:
return Array.prototype.map.call(document.getElementsByTagName('a'), function(a){
return { text: a.innerText, href: a.href };
});

Finding meta “description” using Javascript

I was trying to pass a tab object tabout in order to find the description and title of the webpage.
When I was debugging the code with some breakpoints, it was returning value, but when I am running it, it's not returning the description.
Is there any problem with the code?
function computeDescription(tabout)
{
var code = 'var meta = document.querySelector("meta[name=\'description\']");' +
'if (meta) meta = meta.getAttribute("content");' +
'({' +
' title: document.title,' +
' description: meta || ""' +
'});';
var desc;
var message = document.querySelector('#message');
chrome.tabs.executeScript(tabout.id,{code: code}, function(results) {
if (chrome.extension.lastError) {
message.innerText = 'There was an error injecting script :\n'+chrome.extension.lastError.message;
}
if (!results) {
return;
}
var result = results[0];
// Now, do something with result.title and result.description
console.log(result.title);
console.log(result.description);
desc=result.description;
});
return desc;
}
It looks like you're assuming that the callback you give to executeScript will execute before computeDescription returns. This is not true; executeScript executes asynchronously and your callback will never run before computeDescription returns.
In order to handle this, you need to to adopt the asynchronous model for your definition of computeDescription. Rather than returning a value, take a callback argument and call it when data is ready.
function computeDescription(tabout, callback) {
var code = 'var meta = document.querySelector("meta[name=\'description\']");' +
'if (meta) meta = meta.getAttribute("content");' +
'({' +
' title: document.title,' +
' description: meta || ""' +
'});';
var message = document.querySelector('#message');
chrome.tabs.executeScript(tabout.id, {code: code}, function(results) {
if (chrome.extension.lastError) {
message.innerText = 'There was an error injecting script :\n'+chrome.extension.lastError.message;
}
if (!results) {
callback();
}
callback(results[0].description);
});
}
Then your usage similarly transforms from
console.log('Le description is: ' + computeDescription(tab));
to
computeDescription(tab, function(description) {
console.log('Le description is: ' + description);
});

Categories