Bug when sending array in node.js and socket.io - arrays

I use socket.io version 0.8.4
I have boiled down my problem to the following. I have data looking like this:
data.prop1 = [];
data.prop1.push("man");
data.prop2 = [];
data.prop2["hey"] = "man";
I send the data from the server to the client this way:
socket.emit("data", data);
On the client side I receive the data this way:
socket.on("data", function(data){ console.log(data); });
The weird thing is:
data.prop1 = [];
data.prop1.push("man"); // This data exists in the client side data object
data.prop2 = [];
data.prop2["hey"] = "man"; // This data does not exist.
data.prop2 is just an empty array on the client side.
Is there a known bug in json serializing arrays on the form in prop2?
Thankyou in advance
EDIT:
Problem solved using this workaround:
data.prop1 = [];
data.prop1.push("man");
data.prop2 = {}; // <= Object instead of array
data.prop2["hey"] = "man";

ECMA-262 about JSON.stringify:
The representation of arrays includes only the elements between zero and array.length – 1 inclusive. Named properties are excluded from the stringification.
Arrays are supposed to have numerical property names. So when the data.prop2 is transformed to JSON (which socket.io sends the data in, I imagine), it doesn't get the 'hey' property. If you want to use non-numerical property names, you should use objects instead of arrays:
data.prop1 = [];
data.prop1.push("man");
data.prop2 = {}; // Notice we're creating an object, not an array.
data.prop2["hey"] = "man"; // Alternatively: data.prop2.hey = "man"

Unfortunately, Javascript doesn't really work like that.
Check out this article, about half way down. It explains the problem where you try to set data.prop2["hey"] = "man";

Related

Kotlin Parsing json array with new line separator

I'm using OKHttpClient in a Kotlin app to post a file to an API that gets processed. While the process is running the API is sending back messages to keep the connection alive until the result has been completed. So I'm receiving the following (this is what is printed out to the console using println())
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"DONE","transcript":"Hello, world.","error":null}
Which I believe is being separated by a new line character, not a comma.
I figured out how to extract the data by doing the following but is there a more technically correct way to transform this? I got it working with this but it seems error-prone to me.
data class Status (status : String?, transcript : String?, error : String?)
val myClient = OkHttpClient ().newBuilder ().build ()
val myBody = MultipartBody.Builder ().build () // plus some stuff
val myRequest = Request.Builder ().url ("localhost:8090").method ("POST", myBody).build ()
val myResponse = myClient.newCall (myRequest).execute ()
val myString = myResponse.body?.string ()
val myJsonString = "[${myString!!.replace ("}", "},")}]".replace (",]", "]")
// Forces the response from "{key:value}{key:value}"
// into a readable json format "[{key:value},{key:value},{key:value}]"
// but hoping there is a more technically sound way of doing this
val myTranscriptions = gson.fromJson (myJsonString, Array<Status>::class.java)
An alternative to your solution would be to use a JsonReader in lenient mode. This allows parsing JSON which does not strictly comply with the specification, such as in your case multiple top level values. It also makes other aspects of parsing lenient, but maybe that is acceptable for your use case.
You could then use a single JsonReader wrapping the response stream, repeatedly call Gson.fromJson and collect the deserialized objects in a list yourself. For example:
val gson = GsonBuilder().setLenient().create()
val myTranscriptions = myResponse.body!!.use {
val jsonReader = JsonReader(it.charStream())
jsonReader.isLenient = true
val transcriptions = mutableListOf<Status>()
while (jsonReader.peek() != JsonToken.END_DOCUMENT) {
transcriptions.add(gson.fromJson(jsonReader, Status::class.java))
}
transcriptions
}
Though, if the server continously provides status updates until processing is done, then maybe it would make more sense to directly process the parsed status instead of collecting them all in a list before processing them.

Laravel compare two array

I have to arrays and I have to find difference values from it.
Here is my Laravel Controller code
$product_list = Operation::where('kvit_id', $kvit->id)->pluck('product_id')->toArray();
$hamkor_products = ListProduct::where('user_id', $newkvit->user_id)->pluck('product_id')->toArray();
$operProductList = array_diff($product_list, $hamkor_products);
dd($product_list, $hamkor_products, $operProductList);
Here is result which I'm getting
What kind of mistake I made? $operProductList is returns []
You must just change the order of parameters in array_diff(), it must be like :
$product_list = Operation::where('kvit_id', $kvit->id)->pluck('product_id')->toArray();
$hamkor_products = ListProduct::where('user_id', $newkvit->user_id)->pluck('product_id')->toArray();
$operProductList = array_diff($hamkor_products, $product_list);
dd($product_list, $hamkor_products, $operProductList);

getting data from an object's array with vue.js

I am trying to access the following data in Vue.js
{"id":1,"name":"Westbrook","created_at":"2017-06-10T16:03:07.336Z","updated_at":"2017-06-10T16:03:07.336Z","stats":[{"id":1,"player_id":1,"points":2558,"assists":840,"rebounds":864,"created_at":"2017-06-10T16:03:07.373Z","updated_at":"2017-06-10T16:03:07.373Z"}]}
self.player = response.name works. now i need self.point
methods: {
fetchData: function() {
var self = this;
$.get("api/v1/players/1", function(response) {
console.log(response);
self.player = response.name;
self.point = response.stats.points
});
}
}
I have thus far tried response.stats["points"], response.stats[2], response.stats[ { points } ], response.stats[points]
The stats property in your json holds an array in which the first object has a property named points
So use response.stats[0].points
Keep in mind though that the stats is probably an array for a reason. It might hold more than one objects in the future, so always using the first element [0] might not be a valid approach.
I think it can help you
var json = JSON.parse(data);
json.stats[0].points
response = {"id":1,"name":"Westbrook","created_at":"2017-06-10T16:03:07.336Z","updated_at":"2017-06-10T16:03:07.336Z","stats":[{"id":1,"player_id":1,"points":2558,"assists":840,"rebounds":864,"created_at":"2017-06-10T16:03:07.373Z","updated_at":"2017-06-10T16:03:07.373Z"}]}
If you want to access the name
console.log(response.name) // Westbrook
If you want to access the stats data which contain list, simply target
let stats=response.stats[0] //By getting the first index in the list
Get the points in stats
console.log(stats.points) // 2588

array push of records obtained from mongo db

In MEAN stack, I am trying to store the records obtained from mongo db in an array, but I am not able to store the record in an array.
This is my code, I am trying to push the records obtained from projectimage to fulldetails[] array, but it failed. Suggest me the possible solution to store the mongo db records to array
var express = require("express"),
router = express.Router(),
project = require("../../models/project.js"),
projectimage = require("../../models/projectimages.js"),
var details=data;
var fulldetails=[];
for (var i = 0; i < details.length; i++) {
var prjct_id=details[i]._id;
console.log('below'+i);
fulldetails.push(details[i]);
projectimage.findOne({projectId: prjct_id}, function(err, data){
fulldetails.concat(data);
});
console.log(fulldetails);
return false;
}
I think what do you want is to get an array from your Mongo collection, correct me if I am wrong.
I am also assuming that Mongo query runs successfully, and returns the records correctly. then you can use toArray function to get array in callback.
// let's say Furniture is your collection
let furniture = Furniture.find({});
let details = [];
furniture.toArray((err, array) => {
if (err) return;
details = array; // now details has your collections' documents
});
For more refer this
Let me know if this is not what you were looking for.
I think you're trying to get a flat array of full details. If my assumption is correct, you could try my solution here:
var fulldetails=[];
for (var i = 0; i < details.length; i++) {
var prjct_id=details[i]._id;
projectimage.find({projectId: prjct_id}).toArray(function(err, data){ //convert data to array first
console.log(data);
fulldetails.concat(data); // concat data to fulldetails to get a flat array
});
}

Trouble finding the correct syntax creating vars in objects

Up until now I have been creating var inside the classes I made. e.g.
var backpack:Array = new Array("food", "water");
I want to create objects dynamically now like:
player = {};
player.backpack = ("food", "water"); // not the right syntax
OR
player = {backpack:Array = new Array("food", "water")} // not right either.
Any help? Thanks in advance. I can do this with simple vars like int, but can't find the answer to arrays.
ActionScript's generic object properties don't have any variable type associated with them. You assign them one of the following ways.
Example 1
player = {backpack: new Array("food", "water")};
Example 2
player.backpack = new Array("food", "water");
Example 3
player["backpack"] = new Array("food", "water");
You can use square brackets to define literal arrays. Not only is it shorter, but it's also faster (see this post).
The correct syntax for your two examples are
player = {};
player.backpack = ["food", "water"];
and
player = {backpack: ["food", "water"]};
Also, if you find it easier, you can use it in the first line of code you wrote.
var backpack:Array = ["food", "water"];

Resources