Empty return of variable - javascript

I have this code:
var results_ = ger.recommendations_for_person('movies', query.name, {actions: {likes: 1}});
var recommendations = results_.recommendations;
return recommendations;
ger.recommendations_for_person('movies', query.name, {actions: {likes: 1}});
is meant to return something as such.
{
"recommendations": [
{
"thing": "spiderman",
"weight": 1.6666666666666667,
"last_actioned_at": "2019-05-17T23:06:54+01:00",
"last_expires_at": "2020-06-06T01:00:00+01:00",
"people": [
"bob",
"alice"
]
},
{
"thing": "xmen",
"weight": 1.6666666666666667,
"last_actioned_at": "2019-05-17T23:06:54+01:00",
"last_expires_at": "2020-06-06T01:00:00+01:00",
"people": [
"alice",
"bob"
]
},
{
"thing": "barbie",
"weight": 1,
"last_actioned_at": "2019-05-17T23:06:54+01:00",
"last_expires_at": "2020-06-06T01:00:00+01:00",
"people": [
"alice"
]
},
{
"thing": "avengers",
"weight": 0.6666666666666667,
"last_actioned_at": "2019-05-17T23:06:54+01:00",
"last_expires_at": "2020-06-06T01:00:00+01:00",
"people": [
"bob"
]
}
],
"neighbourhood": {
"bob": 0.6666666666666667,
"alice": 1
},
"confidence": 0.002462038997842016
}
And it works perfectly if I just return results.
But why can't I return recommendations.It returns a blank screen.
My question is different from How do I return the response from an asynchronous call? because for one thing ,I am using nodejs not ajax.It is meant to be synchronous.
This is the full code for `
recc_.js:
var http = require('http'),
url = require('url');
// require the ger objects
http.createServer(function (request, response) {
var query = url.parse(request.url,true).query;
var g = require('../ger')
// Create an Event Store Manager (ESM) that stores events and provides functions to query them
var esm = new g.MemESM()
// Initialize GER with the esm
var ger = new g.GER(esm);
ger.initialize_namespace('movies')
.then( function() {
return ger.events([
////RECCOMMENDATION LISTS
{
namespace: 'movies',
person: 'bob',
action: 'likes',
thing: 'xmen',
expires_at: '2020-06-06'
},
{
namespace: 'movies',
person: 'bob',
action: 'likes',
thing: 'avengers',
expires_at: '2020-06-06'
},
{
namespace: 'movies',
person: 'bob',
action: 'likes',
thing: 'spiderman',
expires_at: '2020-06-06'
},
{
namespace: 'movies',
person: 'alice',
action: 'likes',
thing: 'xmen',
expires_at: '2020-06-06'
},
{
namespace: 'movies',
person: 'alice',
action: 'likes',
thing: 'spiderman',
expires_at: '2020-06-06'
},
{
namespace: 'movies',
person: 'alice',
action: 'likes',
thing: 'barbie',
expires_at: '2020-06-06'
},
////RECCOMMENDATION LISTS
])
})
.then( function() {
// What things might alice like?
var results_ = ger.recommendations_for_person('movies', query.name, {actions: {likes: 1}});
var recommendations = results_.recommendations;
//var results = results_[reccomendations.map(({ thing }) => thing)];
return recommendations;
})
.then( function(recommendations) {
response.end(JSON.stringify(recommendations,null,2))
response.end("\nRecommendations For 'alice'")
})
}).listen(8080);
console.log(' server running ok http://127.0.0.1:8080/');
The implementation for var results_ = ger.recommendations_for_person('movies', query.name, {actions: {likes: 1}}) is :
recommendations_for_person: (namespace, person, configuration = {}) ->
configuration = #default_configuration(configuration)
actions = configuration.actions
#first a check or two
#find_events(namespace, actions: Object.keys(actions), person: person, current_datetime: configuration.current_datetime, size: 100)
.then( (events) =>
return {recommendations: [], confidence: 0} if events.length < configuration.minimum_history_required
return #generate_recommendations_for_person(namespace, person, actions, events.length, configuration)
)

I GOT IT!!!
I just had to do:
.then( function() {
// What things might alice like?
return results_ = ger.recommendations_for_person('movies', query.name, {actions: {likes: 1}});
})
.then(function(results_) {
var recommendations = results_.recommendations;
//var results = results_[reccomendations.m ap(({ thing }) => thing)];
return recommendations;
})
.then( function(recommendations) {
response.end(JSON.stringify(recommendations,null,2))
response.end("\nRecommendations For 'alice'")
})
ie using Promises

Related

How do you check if value exist in object of object's array?

I want to know which logic i should use to check every object's array of parent object contained in grand parent object
Hi guys i want to check if this value for example : "127.0.0.1" exists in this object (MyObject has like 2k objects in it)
{
"name" : MyObject
"value": [
{
"name" : "Object1",
"properties":{
"address" : [
"13.65.25.19/32",
"13.66.60.119/32",
]
}
},
{
"name" : "Object2",
"properties":{
"address" : [
"13.65.25.19/32",
"127.0.0.1",
]
}
}
]
}
Btw does include() needs to match the whole string or for example if 127.0.0.1 is like this in my object 127.0.0.1/32, i can still retrieve it even if there is a ip range ?
Your data is structured quite specifically, so you can write a custom method which you can call over and over again. It will check for a
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '127.0.0.1';
const includesAddress = (address) => {
for (const val of obj.value) {
if (val.properties.address.some((a) => address === a)) return true;
}
return false;
};
console.log(includesAddress(address));
Array.flatMap implementation
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '127.0.0.1';
const output = obj.value.flatMap(item => item.properties.address).includes(address);
console.log(output);
If you want check if the partial ip addess is included in the list, you should make use of a regex implementation.
Sample Implementation
const obj = {
name: 'MyObject',
value: [
{
name: 'Object1',
properties: {
address: ['13.65.25.19/32', '13.66.60.119/32'],
},
},
{
name: 'Object2',
properties: {
address: ['13.65.25.19/32', '127.0.0.1'],
},
},
],
};
const address = '13.65.25.19';
const regex = new RegExp(address, 'i')
const output = obj.value.flatMap(item => item.properties.address).filter(x => regex.test(x)).length > 0;
console.log(output);

Merge two Arrays using underscore.js in AngularJS

I have two api requests and both gets a result of JSON. The first request is "account" request and second is "Container" request. Now:
Request for all Accounts (accountid: 1, name: account1, blabla)
Request for all Containers (accountid: 1, name: Container1, blabla)
This is the result JSON of Accounts:
account: [
{
accountId: "123456789",
fingerprint: null,
name: "Account2",
path: "accounts/123456789",
},
This is the result JSON of Containers:
{
accountId: "123456789",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},
As you can see the container result contains the accountid so im trying to merge those two results so it becomes this combined (container):
{
accountId: "123456789",
name: "Account2", <------ THIS is what i want to merge
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},
Remember there are many containers and accounts not just one block.
What i have tried using underscore:
var mergedList = _.map($scope.GTMcontainers, function(data){
return _.extend(data, _.findWhere($scope.account, { id: data.accountId }));
});
console.log(mergedList);
Here is my AngularJS
function getContainer() {
$http.get("http://******")
.then(function (response) {
$scope.GTMcontainers = response.data;
console.log(response);
$scope.loading = false;
})
.then(function () {
$http.get("http://******")
.then(function (response2) {
$scope.account = response2.data;
console.log(response2);
var mergedList = _.map($scope.GTMcontainers, function(data){
return _.extend(data, _.findWhere($scope.account, { id: data.accountId }));
});
console.log(mergedList);
})
})
}
Using this underscore gives me exactly the same JSON result as i requested (no merge).
Hope some one has experience with this.
Thanks
Updated:
using simple javascript
var accounts = [
{
accountId: "123456789",
fingerprint: null,
name: "Account2",
path: "accounts/123456789",
},{
accountId: "123456780",
fingerprint: null,
name: "Account3",
path: "accounts/123456789",
}]
var containers =[{
accountId: "123456789",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},{
accountId: "123456780",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container24",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
}]
var result=[];
containers.forEach(function(item){
var temp=accounts.find(function(d){return d.accountId == item.accountId});
if(temp)
item.name = temp.name;
result.push(item);
})
console.log(result);
I have faced that issue, I knew I have got responses, but data was not merged. So I have used callbacks.
function getContainer(callback) {
$http.get("http://******")
.then(function (response) {
$scope.GTMcontainers = response.data;
console.log(response);
$scope.loading = false;
})
.then(function () {
$http.get("http://******")
.then(function (response2) {
$scope.account = response2.data;
console.log(response2);
if(response && response2){
callback(response,response2);
}
})
})
}
At function call time--
getContainer(function(array1,array2){
if(array1 && array2 && array1.length>0 && array2.length>0){
var mergedList = _.map(array1, function(data){
return _.extend(data, _.findWhere(array2, { id: data.accountId }));
});
console.log(mergedList);
}
})

Build JS arrays by key into one - find a best solution

What's the best solution to mapping 2 multiple arrays to build one by key?
I have 1 array with users who have their profile data like
var users = [{id:5, name:'Alex'}, {id:17, name:'Tom'}, {id:11, name:'John'}];
Also I have another one array of cars with key user_id To determine which machine belongs to which user.
var cars = [{id:333, name:'Nissan', user_id:11}, {id:444, name:'Toyota', user_id:17}, {id:555, name:'BMW', user_id:999}];
So we can see that Tom have Toyota and John have Nissan.
So result should be
a new array with mapped result
[{
"profile": {
"id": 17,
"name": "Tom"
},
"car": {
"id": 444,
"name": "Toyota",
"user_id": 17
}
}, {
"profile": {
"id": 11,
"name": "John"
},
"car": {
"id": 333,
"name": "Nissan",
"user_id": 11
}
}]
My solution is use forEach throw users and sub forEach throw cars and there compare user.id with car.user_id
https://jsfiddle.net/r7qwke1f/37/
You could use a two loop approach instead of a nested loop approach by collecting first all users in a hash table anbd then iterate all cars and if a user is available, then create a new result set.
var users = [{ id: 5, name: 'Alex' }, { id: 17, name: 'Tom' }, { id: 11, name: 'John' }],
cars = [{ id: 333, name: 'Nissan', user_id: 11 }, { id: 444, name: 'Toyota', user_id: 17 }, { id: 555, name: 'BMW', user_id: 999 }],
hash = {},
result = [];
users.forEach(function (user) {
hash[user.id] = user;
});
cars.forEach(function (car) {
if (hash[car.user_id]) {
result.push({ profile: hash[car.user_id], car: car });
}
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution
const mappedUsersCars = users.map((user) => ({
profile: user,
car: cars.filter((car) => car.user_id === user.id)[0]
}))
You can use reduce() and find() methods to get desired result.
var users = [{id:5, name:'Alex'}, {id:17, name:'Tom'}, {id:11, name:'John'}];
var cars = [{id:333, name:'Nissan', user_id:11}, {id:444, name:'Toyota', user_id:17}, {id:555, name:'BMW', user_id:999}];
var r = users.reduce(function(r, e) {
var car = cars.find(a => a.user_id == e.id);
if(car) r.push({profile: e, car: car});
return r;
}, [])
console.log(r)
There are basically two methods you would want to use. You want to map the users to the cars, so you want to find a car for the user you are referring to
const result = users.map((user) => {
const car = cars.find(car => car.user_id === user.id);
return {
profile: user,
car,
}
})

How can i calculate the response time in the below code and print it on the console

describe("Prefabs basic", function() {
it("It should create simple plrefab", function(done) {
var data = {
name: "Pre",
project: {
_id: settings.projectId,
name: "PM_40"
},
__t: "Prefabs",
stage: "planning",
multiTrade: {
value: false,
companies: []
},
owner: {
user: {
_id: ""
},
company: {
_id: ""
}
},
_customStage: "planning",
dates: [],
dateIndices: {
additional: {},
coord: 0,
deliver: 1
},
fileIndices: [],
todoIndices: [0],
new_prefab: true,
todos: [],
items: {
fileIndices: [],
todoIndices: [],
customId: "1",
name: "Item0",
level: "1",
zone: "west"
},
keywords: ["This is Prefab"]
};
chai
.request(server)
.post("/v3/prefabs/create")
.set("Authorization", settings.authKey)
.send(data)
.end(function(err, res) {
res.should.have.status(200);
prefab = res.body;
prefabId = res.body._id;
console.log(prefab);
});
});
});
I took the liberty of formatting your code so it is slightly more readable - in general you will get a better response to your questions if you present a question that is easy to understand. With that said, you can use process.hrtime() to time things in Node. For example,
it('does something', function() {
const startTime = process.hrtime();
chai
.request(server)
.post("/v3/prefabs/create")
.set("Authorization", settings.authKey)
.send(data)
.end(function(err, res) {
res.should.have.status(200);
const timeDifference = process.hrtime(startTime);
console.log(`Request took ${timeDifference[0] * 1e9 + timeDifference[1]} nanoseconds`);
});
});

Aggregate using external references in mongodb

I'd like to aggregate results in a mongodb query, however I am not able to accomplish that in the case modeled like the following example from mongodb.org:
{
_id: "oreilly",
name: "O'Reilly Media",
founded: 1980,
location: "CA"
}
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly"
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher_id: "oreilly"
}
My result should have this structure:
{
publishers: [
{
_id: "oreilly",
name: "O'Reilly Media",
founded: 1980,
location: "CA"
books: [
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English"
},
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher_id: "oreilly"
}
]
}
]
}
But I cannot manage to use the $aggregate query on the books table to populate the publisher reference, and I don't even know if it is possible.
What are the proper strategies to get this kind of result?
One way to get the result is to simulate the join by iterate each publisher to find his books and then construct your result :)
sample in mongo shell:
var publishers = [];
var struct = {};
struct.publishers = publishers
db.publisher.find().forEach( function(publisher) {
publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
publishers.push(publisher)
})
printjson(struct)
sample for drivers:
You can use db.eval to run a query as Server-side Javascript.
db.eval:
connection.db.eval(function construct(publisher){return struct}), arg ,function (e, result) {result});
db.eval function:
db.eval(function construct(publisher) {
var publishers = [];
var struct = {};
var query = publisher ? {_id:publisher} : {}
struct.publishers = publishers
db.publisher.find(query).forEach( function(publisher) {
publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
publishers.push(publisher)
})
return struct
}
,null // argument to pass into function for filter, e.g. 'oreilly'
,{nolock:true})
sample with mongoose: (on collection name book)
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/book');
mongoose.connection.on('connected', function() {
mongoose.connection.db.eval(function construct(publisher) {
var publishers = [];
var struct = {};
var query = publisher ? {_id:publisher} : {}
struct.publishers = publishers
db.publisher.find(query).forEach( function(publisher) {
publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
publishers.push(publisher)
})
return struct
}
,'oreilly'
,{nolock:true}, function(e,result) {
if(e) console.log(e);
console.log(JSON.stringify(result));
})
})

Categories

Resources