emit to specifics sockets (like a whisper) which contain specific socket.name - node.js

I have my sockets stored like this in an object "people" . but now I would like to extract coincidences in people.name with an object like ["4323","9","43535"] for example 9. meaning extract in this case "OGyF_FMFbsr0ldcbAAAK" socket.
In a few words navigate through ["4323","9","43535"] and find if they are in people , so then emit a notification to the socket which contain people.name === 9 . Could be more than one socket.
So.
for each "attending"
["4323","9","43535"]
in "people"
{
"ZA-CJOc1PtiwDVxkAAAD":
{"name":"4","owns":"2-0-62","inroom":"2-0-62","device":"desktop"},
"wKg2rcFSHgcl4m3WAAAG":
{"name":"3","owns":"2-0-110","inroom":"2-0-110","device":"desktop"},
"OGyF_FMFbsr0ldcbAAAK":
{"name":"9","owns":null,"inroom":null,"device":"desktop"}
}
then emit
io.sockets.socket(id).emit("notification", result);
QUESTIONS:
How do I make the right code to select sockets to send notification?
How then would emit the notification for each one?
thanks in advance

If I understand what you're asking correctly, then one way to do this is to iterate over the keys of your people object, compare the name properties of each of them with the elements in your attending array, and push any matching keys into a new array found to get a list of people whose name is found in your attending list.
You can then iterate over the found array to emit messages to clients in your people object that match your search criteria.
var attending = ['4323', '9', '43535'],
found = [];
var people = {
'ZA-CJOc1PtiwDVxkAAAD': {
'name': '4', 'owns': '2-0-62', 'inroom': '2-0-62', 'device': 'desktop'
},
'wKg2rcFSHgcl4m3WAAAG': {
'name': '3', 'owns': '2-0-110', 'inroom': '2-0-110', 'device': 'desktop'
},
'OGyF_FMFbsr0ldcbAAAK': {
'name': '9', 'owns': null, 'inroom': null, 'device': 'desktop'
}
};
for (var person in people) {
for (var i = 0, numAttending = attending.length; i < numAttending; i++) {
if (people[person].name === attending[i]) {
found.push(person);
}
}
}
for (var i = 0, numFound = found.length; i < numFound; i++) {
io.sockets.socket(found[i]).emit('notification', result);
};
Edit
If you want to push whole objects onto your found array, you could do it like this. Since the entire object and not only the client id is being stored in the array, the emit loop below needs some slight adjusting to keep working.
for (var person in people) {
for (var i = 0, numAttending = attending.length; i < numAttending; i++) {
if (people[person].name === attending[i]) {
found.push(people[person]);
//this would give something like this, without the socket id
//[{"name":"3","owns":null,"inroom":null,"device":"desktop"}]
}
}
}
for (var person in found) {
io.sockets.socket(person).emit('notification', result);
};

Related

Best way to search march in an array of JavaScript Objects?

I'm facing a challenge to match values within an array of JS objects. Let me give you an example,
var dynamicObjectArray = [
{Id: 1422859025, FromTime: "2023-02-12T19:00:00Z", ToTime: "2023-02-12T20:00:00Z"},
{Id: 1422859027, FromTime: "2023-02-12T18:00:00Z", ToTime: "2023-02-12T19:00:00Z"}
]
I need to find all Ids for FromTime or ToTime match with "2023-02-12T19:00:00Z"
Using a database, it can be done easily. But, here, I need to play an array of 100 objects max. Also, data will be dynamic. Can you please suggest me a way to achieve the goal using NodeJS.
You could use the JS Date builtin constructor to compare dates instead of using the string directly.
Filter your matching objects, and map the ids.
You can do something like this.
const dynamicObjectArray = [{
Id: 1422859025,
FromTime: "2023-02-12T19:00:00Z",
ToTime: "2023-02-12T20:00:00Z"
},
{
Id: 1422859027,
FromTime: "2023-02-12T18:00:00Z",
ToTime: "2023-02-12T19:00:00Z"
}
];
const matchTime = new Date("2023-02-12T19:00:00Z").getTime();
const matchIds = dynamicObjectArray.filter(obj => {
const fromTime = new Date(obj.FromTime).getTime();
const toTime = new Date(obj.ToTime).getTime();
return matchTime === fromTime || matchTime === toTime;
}).map(obj => obj.Id);
console.log(matchIds);
If you want a suggestion, you can do something like this:
Create a function that takes as a parameter, the wanted Date
Create a variable containing an array where you will save all those "id's" that match your condition
Create a for loop
Create an if condition, that matches the following condition:
if date exists on "FromTime" or exists on "ToTime", push to your "id's array"
Return your ids array
Here is the code implementation:
function filterObjByDate(TO_MATCH_DATE) {
let ids = [];
for (let i = 0; i < dynamicObjectArray.length; i++) {
if (
dynamicObjectArray[i].FromTime === TO_MATCH_DATE ||
dynamicObjectArray[i].ToTime === TO_MATCH_DATE
) {
ids.push(dynamicObjectArray[i].Id);
}
}
return ids
}
That's it. If you have more question, ask me 😀👍

How to remove specific object from object array in localStorage

Can anybody advise me how I should go about adapting this code to remove the found object within an array of objects in localStorage.
So far everything I have tried results in either only the 1st object being removed or none at all.
I have tried using the following adaptations to the splice request, but it has not removed the selected object.
favorites.splice(favorites, [i]);
favorites.splice(favorites, 1);
favorites.splice(favorites, favorites[i]);
ect ect
I have also tried using the ifIncludes request but then again removing the individual object has been troublesome.
function checkfave (theid) {
// get favorites from local storage or empty array
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
var theprice = $('#theprice'+theid).text();
var added=true;
//Loop through the Favorites List and display in console (HIDDEN)
console.clear();
for (let i = 0; i < favorites.length; i++) {
console.log(i)+'items added';
if ( favorites[i].ID == theid ) {
var answer = window.confirm('You already Added To Your Favorites \r\r '+thetitle+' \r\r Do You Want To Remove It? ');
if (answer) { // choose to remove
favorites.splice(favorites[i], [i]);
alert(thetitle+' \r\r Has Been Removed From Your Favorites \r\r At Position'+[i]);
var added=false; break; //IMPORTANT KILLS THE LOOP ONLY IF favorites[i].ID == theid
}else {
var added=false; break;
}
}
}//for loop
if (added===true) {
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle,PRICE:theprice});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added To Your Favorites \r\r '+thetitle);
}
console.log(localStorage.favorites);
}//function
console log is returning in this format
favorites
(2) [{…}, {…}]
0
:
{ID: 32921, IMAGE: 'uploads/posts/2017-07/1500056645_apulsoft-apqualizr-2.png', TITLE: 'ApulSoft apQualizr 2 v2.5.2 ', PRICE: '19.99'}
1
:
{ID: 32920, IMAGE: 'uploads/posts/2022-03/1003229…cdj-lyrx-karaoke-player-software-for-mac-pc-1.png', TITLE: 'PCDJ LYRX v1.8.0.2 / v1.9.0.0 U2B ', PRICE: '19.99'}
length
:
2
[[Prototype]]
:
Array(0)
`
Finally figured it out on my own. Thanks
for (let i = 0; i < favorites.length; i++) {
console.log(i)+'items added';
if ( favorites[i].ID == theid ) {
var answer = window.confirm('You already Added To Your Favorites \r\r '+thetitle+' \r\r Do You Want To Remove It? ');
if (answer) { // choose to remove
favorites.splice(i, 1);
localStorage.setItem('favorites', JSON.stringify(favorites));
alert(thetitle+' \r\r Has Been Removed From Your Favorites \r\r At Position'+[i]);
var added=false; break; //IMPORTANT KILLS THE LOOP ONLY IF favorites[i].ID == theid
}else {
var added=false; break;
}
}
}//for loop
I was misunderstanding the nature of the splice function. i was trying to use favourites[i] = when favorites was already assumed in the 1st instance of the splice call.
I eventually came across the answer online in a similar situation.
the answer was to splice this way to remove at position i and remove 1 item
favorites.splice(i, 1);
Thanks anyway guys.

Get records by page wise in Netsuite using RESTlet

i want to get all the records in particular record type , but i got 1000 only.
This is the code I used.
function getRecords() {
return nlapiSearchRecord('contact', null, null, null);
}
I need two codes.
1) Get whole records at a single time
2) Get the records page wise by passing pageindex as an argument to the getRecords [1st =>0-1000 , 2nd =>1000 - 2000 , ...........]
function getRecords(pageIndex) {
.........
}
Thanks in advance
you can't get whole records at a time. However, you can sort results by internalid, and remember the last internalId of 1st search result and use an additional filter in your next search result.
var totalResults = [];
var res = nlapiSearchRecord('contact', null, null, new nlobjSearchColumn('internalid').setSort()) || [];
lastId = res[res.length - 1].getId();
copyAndPushToArray(totalResult, res);
while(res.length < 1000)
{
res = nlapiSearchRecord('contact', null, ['internalidnumber', 'greaterthan', lastId], new nlobjSearchColumn('internalid').setSort());
copyAndPushToArray(totalResult, res);
lastId = res[res.length - 1].getId();
}
Beware, if the number of records are high you may overuse governance limit in terms of time and usage points.
If you remember the lastId you can write a logic in RESTlet to take id as param and then use that as additional filter to return nextPage.
You can write a logic to get nth pageresult but, you might have to run search uselessly n-1 times.
Also, I would suggest to use nlapiCreateSearch().runSearch() as it can return up to 4000 records
Here is another way to get more than 1000 results on a search:
function getItems() {
var columns = ['internalid', 'itemid', 'salesdescription', 'baseprice', 'lastpurchaseprice', 'upccode', 'quantityonhand', 'vendorcode'];
var searchcolumns = [];
for(var col in columns) {
searchcolumns.push(new nlobjSearchColumn(columns[col]));
}
var search = nlapiCreateSearch('item', null, searchcolumns);
var results = search.runSearch();
var items = [], slice = [], i = 0;
do {
slice = results.getResults(i, i + 1000);
for (var itm in slice) {
var item = {};
for(var col in columns) { item[columns[col]] = slice[itm].getValue(columns[col]); } // convert nlobjSearchResult into simple js object
items.push(item);
i++;
}
} while (slice.length >= 1000);
return items;
}

how to find specific string in key value pair in mongodb

i am having data in mongodb like that
[
{
"name":"silvester",
"product":"laptop,iphone,mobile,phone"
},
{
"name":"john",
"product":"cycle,bus,phone,laptop"
},
{
"name":"franklin",
"product":"cycle,phone"
}
]
How to find that laptop is in product key.
if product key look like this
{
"name":"XXX",
"product":"laptop"
}
I can easily find that name by using this db.collection.find("product":"laptop");
So how to find this?
Also let me know this three website name running under using backbone.js and node.js and mongodb technology such as www.trello.com .
sorry for my worst english..
Using regex with mongodb
This worked for me
db.collection.find({"product": /laptop/})
Updated Answer
If you wish to use variables, try something like this:
var abc = "laptop";
// other stuff
userdetails.find({"product":new RegExp(abc)}).toArray(function(err,result){
if (err) console.log ("error: "+err);
else
{
// if you want the length
console.log(result.length);
// if you actually want to see the results
for (var i = 0; i < result.length; i++)
{
console.log(result[i]);
}
}
});
Updated One More Time
var abc = "laptop";
// other stuff
// note this is case sensitive. if abc = "Laptop", it will not find it
// to make it case insensitive, you'll need to edit the RegExp constructor
// to this: new RegExp("^"+abc+",|, "+abc+"(?!\w)", "i")
userdetails.find({"product":new RegExp("^"+abc+",|, "+abc+"(?!\w)")}).toArray(function(err,result){
if (err) console.log ("error: "+err);
else
{
// if you want the length
console.log(result.length);
// if you actually want to see the results
for (var i = 0; i < result.length; i++)
{
console.log(result[i]);
}
}
});
regex will work perfectly fine. there is also good news for you as monogdb will be releasing full text search index in the upcoming version
http://docs.mongodb.org/manual/release-notes/2.4/#text-indexes

Map/Reduce differences between Couchbase & CloudAnt

I've been playing around with Couchbase Server and now just tried replicating my local db to Cloudant, but am getting conflicting results for my map/reduce function pair to build a set of unique tags with their associated projects...
// map.js
function(doc) {
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], doc._id);
}
}
}
// reduce.js
function(key,values,rereduce) {
if (!rereduce) {
var res=[];
for(var v in values) {
res.push(values[v]);
}
return res;
} else {
return values.length;
}
}
In Cloudbase server this returns JSON like:
{"rows":[
{"key":"3d","value":["project1","project3","project8","project10"]},
{"key":"agents","value":["project2"]},
{"key":"fabrication","value":["project3","project5"]}
]}
That's exactly what I wanted & expected. However, the same query on the Cloudant replica, returns this:
{"rows":[
{"key":"3d","value":4},
{"key":"agents","value":1},
{"key":"fabrication","value":2}
]}
So it somehow only returns the length of the value array... Highly confusing & am grateful for any insights by some M&R ninjas... ;)
It looks like this is exactly the behavior you would expect given your reduce function. The key part is this:
else {
return values.length;
}
In Cloudant, rereduce is always called (since the reduce needs to span over multiple shards.) In this case, rereduce calls values.length, which will only return the length of the array.
I prefer to reduce/re-reduce implicitly rather than depending on the rereduce parameter.
function(doc) { // map
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], {id:doc._id, tag:doc.tags[t]});
}
}
}
Then reduce checks whether it is accumulating document ids from the identical tag, or whether it is just counting different tags.
function(keys, vals, rereduce) {
var initial_tag = vals[0].tag;
return vals.reduce(function(state, val) {
if(initial_tag && val.tag === initial_tag) {
// Accumulate ids which produced this tag.
var ids = state.ids;
if(!ids)
ids = [ state.id ]; // Build initial list from the state's id.
return { tag: val.tag,
, ids: ids.concat([val.id])
};
} else {
var state_count = state.ids ? state.ids.length : state;
var val_count = val.ids ? val.ids.length : val;
return state_count + val_count;
}
})
}
(I didn't test this code, but you get the idea. As long as the tag value is the same, it doesn't matter whether it's a reduce or rereduce. Once different tags start reducing together, it detects that because the tag value will change. So at that point just start accumulating.
I have used this trick before, although IMO it's rarely worth it.
Also in your specific case, this is a dangerous reduce function. You are building a wide list to see all the docs that have a tag. CouchDB likes tall lists, not fat lists. If you want to see all the docs that have a tag, you could map them.
for(var a = 0; a < doc.tags.length; a++) {
emit(doc.tags[a], doc._id);
}
Now you can query /db/_design/app/_view/docs_by_tag?key="3d" and you should get
{"total_rows":287,"offset":30,"rows":[
{"id":"project1","key":"3d","value":"project1"}
{"id":"project3","key":"3d","value":"project3"}
{"id":"project8","key":"3d","value":"project8"}
{"id":"project10","key":"3d","value":"project10"}
]}

Resources