how to access /obtain object elements from an observable array - arrays

I would like to know how I can obtain an obtain an objects item(LicenseNo) from an observable array. I have pasted my code below , after inserting breakpoints I noticed that I am currently getting the entire objects array as in [LicenseNo , name , allocated route , licenseDate] I just want to get the LicenseNo
function getDriverList(item) {
if (!pageViewModel.isAuthenticated()) return;
var dfd = jQuery.Deferred();
var LicenseNo = ko.observableArray([]);
$.when(getSecureData("/api/FleetDrivers/" + item.NationalID))
.done(function (resp) {
pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList);
if (pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList).length > 0) {
LicenseNo = pageViewModel.vehicelDriversVM.FleetDriverList()[0];
alert('The first driver's License Number is ' LicenseNo;
}
});
return dfd.promise();
}
the code above didnt work so I have pasted the correct one below for anyone who might run into a similar prob
function getDriverList(item) {
if (!pageViewModel.isAuthenticated()) return;
var dfd = jQuery.Deferred();
var LicenseNo = ko.observableArray();
$.when(getSecureData("/api/FleetDrivers/" + item.NationalID))
.done(function (resp) {
pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList);
LicenseNo = resp.FleetDriverList[1];
alert('The first driver's License Number is ' + LicenseNo);
});
return dfd.promise();
enter code here

Related

Nodejs S3 Delete Multiple Objects Error

I am trying to bulk delete my s3 objects that are associated with one specific blog record in my database, but I'm getting hung up on how to pass the array to my params object to be used in the s3.deleteObjects method, but I'm held up on this error: Check with error message InvalidParameterType: Expected params.Delete.Objects[0].Key to be a string. I feel like it could be related to not having a loop at some point in the process or maybe the format of the values being passed to my s3File array.
Here is the my routing:
.delete(function(req, res){
models.File.findAll({
where: {
blogId: blog.blogId
}
}).then(function(file){
var s3Files = [];
function s3Key(link){
var parsedUrl = url.parse(link);
var fileName = parsedUrl.path.substring(1);
return fileName;
}
for(var k in file){
console.log('Here are each files ' + file[k].fileName);
s3Files.push(s3Key(file[k].fileName));
}
console.log('Here are the s3Files ' + s3Files);
//GOTTEN TO THIS POINT WITHOUT AN ERROR
aws.config.update({accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, region: process.env.AWS_REGION});
//var awsKeyPath = s3Key(file.fileName);
var s3 = new aws.S3();
var options = {
Bucket: process.env.AWS_BUCKET,
Delete: {
Objects: [{
Key: s3Files
}],
},
};
s3.deleteObjects(options, function(err, data){
if(data){
console.log("File successfully deleted");
} else {
console.log("Check with error message " + err);
}
});
});
Here is the output from console.log('Here are each files ' + file[k].fileName);:
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-12/screen_shot_2017-02-01_at_8_25_03_pm.png
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-13/test.xlsx
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-13/screen-shot-2017-02-08-at-8.23.37-pm.png
Here is the output from console.log('Here are the s3Files ' + s3Files);:
Here are the s3Files 1/2017-02-12/screen_shot_2017-02-01_at_8_25_03_pm.png,1/2017-02-13/test.xlsx,1/2017-02-13/screen-shot-2017-02-08-at-8.23.37-pm.png
Here is the error message:
Check with error message InvalidParameterType: Expected params.Delete.Objects[0].Key to be a string
Key should be a string. You should use array of Object to Objects.
Use this code :
var objects = [];
for(var k in file){
objects.push({Key : file[k].fileName});
}
var options = {
Bucket: process.env.AWS_BUCKET,
Delete: {
Objects: objects
}
};
Change your array as an object
const objects = [
{Key: 'image1.jpg'},
{Key: 'image2.jpg'}
]
Add a new item to the list
for(var k in file){
objects.push({Key : file[k].fileName});
}
Set the array as Objects value in parameters
const options = {
Bucket: process.env.BUCKET,
Delete: {
Objects: objects,
Quiet: false
}
};
Now delete objects
s3.deleteObjects(options, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
Learn more from official docs

array showing undefined in variable

I have imorted a module that performs a function on an array of data. When I run the function I get the results in my server but they seem not to be stored in my variable, which comes back undefined. Can someone tell me why my array comes back undefined when I can see the array in my server?
var net = require('net');
var foo = require('./employeeModule');
var _ = require('underscore');
var colors = require('colors/safe');
var server = net.createServer(
function(socket){
console.log("Client connection...");
socket.on('end', function(){
console.log("Client disconnected...");
});
// process data from client
socket.on('data', function(data){
var command = data.toString();
var results={};
console.log("Received Command: " +command);
if (command == "lookupByLastName Smith")
{
function lastName(results)
{
var results = foo.lookupByLastName('Smith');
console.log('These are the results: '+ results)
}
lastName();
}
else if (command == "addEmployee William Smith")
{
function addEmp(results)
{
var results = foo.addEmployee('William', 'Smith');
console.log('These are the results: '+ results)
}
addEmp();
}
else if (command == "lookupById 4")
{
function lookId(results)
{
var results = foo.lookupById(4);
console.log('These are the results: '+ Name)
}
lookId();
}
else if (command == "bye")
client.end();
else console.log(colors.green("**"+command+" Command not recognized!**"));
});
});
//listent for client connections
server.listen(1000, function(){
console.log("Listening for client connections");
});
First, what is wrong with your code:
var results={}: the var results is not used.
you have 3 functions lastName, addEmp and lookId. All are called and nothing is passed, therefore the results var is always undefined.
inside every of those functions you are defining another var results, so, nothing is done with the results parameter (like overwriting it).
in lookId the var Name it is undefined.
I suppose that you have the parameters hardcoded (commands, like William Smith, 4 or Smith) because it is some type of "test"/learning exercise. I would not recommend you to define the 3 functions inside the callback function (because they are defined every time it is called the callback).
If you want to keep the results do this (following your type of coding):
function addEmp(){
var res = foo.addEmployee('William', 'Smith');
console.log("There asre the results: " + res);
return res;
}
results = addEmp(); // now you set the value to results
Following more or less what would you do, I would do something like (be careful, I change a bit the type of coding and boundaries/inputs are not controlled):
function lastName(surname){
return foo.lookupByLastName(surname);
}
function addEmp(name, surname){
return foo.addEmployee(name, surname);
}
// ...
function socketData(data){
var args = data.toString().split(' '); // assuming space as splitter
var results;
var command = args[0];
switch(command){
case 'lookupByLastName':
results = lastName(args[1]);
break;
case 'addEmp':
results = addEmp(args[1], args[2]);
break;
default:
// ...
}
// do something with results
}
var server = net.createServer(function(socket){
// ...
socket.on('data', socketData);
// ...
});

Transfer Items to and from users Using AngularJS and Firebase

Ok, so I'm working with AngularJS and Firebase and trying to create a simple exchange between two users. Right now my data structure is set up under "users/uId/" and then their email, date they joined, and gold.
Under gold (users/uId/gold) I have "sent" which captures the amount, time and to whom (email). This is the code snippet below. It also updates their total gold.
Now I'm stuck updating the person they're sending the gold to. I capture the email address, but everything under scope relates to the current logged in user. How would I update the new users users/uId/gold/received with the amount, time and email who it was from, along with updating their total gold?
I feel like I might be going about this the wrong way, any help would be appreciated, thanks!
ledger.controller('TransferController', function (
$scope, $firebase, $routeParams, $location, $rootScope, FIREBASE_URL) {
$scope.whichuser = $routeParams.uId;
$scope.goldsends = goldsendList;
var ref = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/' + '/sent/');
var hopperRef = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/');
var usersRef = ref.child("users");
var goldsendList = $firebase(ref).$asArray();
$scope.sendGold = function () {
var sendgoldObj = $firebase(ref); //this var has to match the sendgoldObj.$push var down below, and that's it
var myData = {
amount: $scope.user.amount,
email: $scope.user.email,
date: Firebase.ServerValue.TIMESTAMP
};
sendgoldObj.$push(myData).then(function () {
// $location.path('/myledger/'); //page redirect
}); //data sent to firebase.
if ($scope.currentUser.gold.total - Math.abs($scope.user.amount) > 0) { //
var hopperRefff = hopperRef.child("gold");
hopperRef.update({
"total": $scope.currentUser.gold.total - $scope.user.amount
}); //update total gold
var receive = new Firebase(FIREBASE_URL);
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
console.log(snap.name() + (snap.val() === null ? ' DOES NOT' : ' does') + ' exist');
}); //trying to find user to send gold to
} //if user has enough gold statement
else {
return {
scope: {
errormessage: 'You don\'t have enough money',
}
};
console.log("not enough money!");
} //else note enough gold statement
} //sendgold
}); //TransferController
You could store the users by email where the # is replaced by _ and a . is replaced with -
So you have a JSON structure like this in Firebase
users: {
"bob_hoskins-com": {
email: "bob#hoskins.com",
date: "09-09-1999",
gold: {
...
}
}
}
However, I don't think this is a great approach for this problem.
I would create a node service that is observing a requests Firebase location on each user for added children. The node service will then do the calculations and write the data to the correct paths, then can delete the request once processed.
So you would have rules on your Firebase like this
{
"rules": {
"$userId": {
"requests": {
".read": "auth != null && $userId == auth.id",
".write": "auth != null && $userId == auth.id"
},
"responses": {
".read": "auth != null && $userId == auth.id",
".write": "auth != null && $userId == auth.id"
}
}
}
Here is some request code
var Firebase = require('firebase');
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
function guid() {
return s4() + s4() + s4() + s4();
}
var _ref = new Firebase('https://YOUR_FIREBASE.firebaseio.com/');
//Log me in
var guid = guid();
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator("YOUR_TOKEN");
var TOKEN = tokenGenerator.createToken({uid: guid, user: "node server"},{admin: true});
_ref.authWithCustomToken(TOKEN, function (error) {
if(error) {
console.log("Login Failed!", error);
} else {
console.log("Login Succeeded!", guid);
}
});
_ref.on('child_added', function (user) {
var requests = user.ref().child('requests');
requests.on('child_added', function(req) {
handleRequest(req);
});
});
var handleRequest = function (request) {
// Process the request
// Write stuff back to Firebase
// Delete the request
request.ref().remove();
};
Setting a value to the user is just a variation of checking if that user exists. Once you have a snapshot, you can get back to a ref by calling ref
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
snap.ref().update({ "total": snap.val().total + amount });
});
Not that this is just a sample, so you'll probably have to update it for your actual data structure.
Update
The above will get you the value of the users node.
You either need to capture the once('child_added' or forEach over the on('value'. I'll give an example of both.
Listening to child_added:
ref.child('users').orderByChild('email').equalTo(emailAddress).once('child_added', function (snap) {
snap.ref().update({ "total": snap.val().total + amount });
});
An example of looping over the value:
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
snap.forEach(function(childsnap) {
childsnap.ref().update({ "total": snap.val().total + amount });
});
Here's a jsbin with both samples: http://jsbin.com/fenavu/1/edit?js,console. Note that the code here writes out the ref.toString(), which gives you the full URL of the node (since every piece of data in Firebase has its own unique URL). That can be a handy way to figure out what URL your node maps to.

How to extend returned objects in the list returned by $asArray?

I'm having trouble decorate the objects in my list returned by $asArray in angularfire with a new method (not decorating the array itself).
The angularfire documentation seems to suggest that the right way to do this is to override the $$added method in the factory for $FirebaseArray, returning a new object that either encapsulates or extends the snapshot that gets passed in to that method. From the documentation:
// an object to return in our JokeFactory
app.factory("Joke", function($firebaseUtils) {
function Joke(snapshot) {
this.$id = snapshot.name();
this.update(snapshot);
}
Joke.prototype = {
update: function(snapshot) {
// apply changes to this.data instead of directly on `this`
this.data = snapshot.val();
},
makeJoke: function() {
alert("Why did the " + this.animal + " cross the " + this.obstacle + "?");
},
toJSON: function() {
// since we didn't store our data directly on `this`, we need to return
// it in parsed format. We can use the util function to remove $ variables
// and get it ready to ship
return $firebaseUtils.toJSON(this.data);
}
};
return Joke;
});
app.factory("JokeFactory", function($FirebaseArray, Joke) {
return $FirebaseArray.$extendFactory({
// change the added behavior to return Joke objects
$$added: function(snap) {
return new Joke(snap);
},
// override the update behavior to call Joke.update()
$$updated: function(snap) {
this.$getRecord(snap.name()).update(snap);
}
});
});
However, when I do this in my code, nothing ever gets added to the array, although I can see from outputting to the console that it is getting called.
var printMessageObjConstructor = function(snap) {
this.$id = snap.name();
this.snapshot = snap;
this.$update = function(snap) {
this.snapshot = snap;
};
this.printMessage = function() {
return this.author + "'s question is: " + this.body;
};
};
var ref = new Firebase("https://danculley-test.firebaseio.com/questions");
//What Am I Doing Wrong Here?
var arrayFactory = $FirebaseArray.$extendFactory({
$$added: function(snap, prevChild) {
var x = new printMessageObjConstructor(snap);
console.log("I am being called from FirebaseDecoratedCtlOverloadAddedinNewObj.");
return x;
},
$createObject: function(snap) {
return new printMessageObjConstructor(snap);
},
$$updated: function(snap) {
var i = this.$indexFor(snap.name());
var q = this.$list[i];
q.$update(snap);
}
});
var sync = $firebase(ref, {arrayFactory:arrayFactory});
var list = sync.$asArray();
list.$loaded(function(list) {
$scope.questions = list;
});
I've set up a new plunk stripped down to show the issue with a couple other use cases that I've tried. (The actual method I'm adding is more complex and isn't related to the view, but I wanted to do something simple to reproduce the issue.)
I think the issue is that I don't quite understand what exactly $$added is supposed to return, or what additional behavior beside returning the value to be stored $$added is supposed to have. There also doesn't really seem to be an $$added on the prototype or on $FirebaseArray to call as a super to get the default behavior. Can someone point me in the right direction?
UPDATE
For the benefit of others, after reviewing the like that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}
For the benefit of others, after reviewing the link that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}

node.js loop through array to write files

I've been working through a few others, also this of looping through array to http.get data from a variety of sources. I understand that nodeJS is working asynchronously which is allowing the files to be written empty or with incomplete data, but I can't seem to get past this point.
Problem: calls are made, files are built but the files are always empty
Goal: loop through an array to create files locally from the sites data. Here is what I've got so far:
var file_url = 'http://js.arcgis.com/3.8amd/js/esri/',
DOWNLOAD_DIR = './esri/',
esriAMD = [ '_coremap.js', 'arcgis/csv.js'];
function readFile(callback) {
if (esriAMD.length > 0) {
var setFile = esriAMD.shift(),
file_name = url.parse(file_url).pathname.split('/').pop(),
trial = setFile.split('/').pop(),
file = fs.createWriteStream(DOWNLOAD_DIR + trial);
http.get(file_url + esriAMD, function(res) {
res.on('data', function(data) {
file.write(data);
console.log(setFile + ' has been written successfully');
});
res.on('end', function(){
console.log(setFile + ' written, moving on');
console.log(esriAMD.length);
readFile(callback);
});
//readFile(callback);
});
} else {
callback();
}
}
readFile(function() {
console.log("reading finishes");
});
Any insight would really help.
thanks,
var esriAMD = [....];
...
function readFile(callback) {
...
http.get(file_url + esriAMD, function(res) {
...
concatenating strings with arrays may yield unexpected results.
you want to make sure that
you know what URLs your program is accessing
your program deals with error situations (where the fsck is res.on('error', ...)?)
Solution: I was passing the wrong variable into the http.get
Working code:
var file_url = 'http://.....',
DOWNLOAD_DIR = './location/';
esriAMD = ['one', 'two', 'three'..0;
function readFile(callback) {
if(esriAMD.length > 0) {
var setFile = esriAMD.shift(),
file_name = url.parse(setFile).pathname.split('/').pop(),
trial = setFile.split('/').pop(),
file = fs.createWriteStream(DOWNLOAD_DIR + trial);
http.get(file_url + setFile, function(res){
res.on('error', function(err){
console.log(err);
});
res.on('data', function(data){
file.write(data);
console.log(setFile + ' started');
});
res.on('end', function(){
console.log(setFile + ' completed, moving on');
});
});
} else {
callback();
}
}

Resources