I have these values stored in a .json as a very basic xp system (im aware of corruption issues, like to learn json before moving to db)
"267752827723492576":{"xp":308,"level":1}, "267752827723492576":{"xp":308,"level":1}
i want to import userid, xp, and level into a variable so i can make a leaderboard command, i already have working code for doing the comparison and sorting (below) . "user" being the variable containing my data from the json file
var users = {
"":{"xp":0,"level":0},
"":{"xp":0,"level":0},
"":{"xp":0,"level":0},
"":{"xp":0,"level":0},
"":{"xp":0,"level":0},
};
let board = Object.entries(users)
.map(([key, val]) => ({id: key, ...val}))
.sort((a, b) => b.xp- a.xp);
console.log(board);
Post is not clear, but you just wan't to import json?
const users = require("path_to.json")
You can also use fs.readFile alongside JSON.parse
Also instead of using an object to store the data you can use an array
with this format: (same format after you used your map method)
[{ id: "", xp: 200, level: 2}]
For preformance both have ups and downs, for actually getting a user by id an object is probably faster, but since you have to use Object.entries and map it probably evens out
Incase you do switch to array, here's how you would fetch a user
// ... just stands for data here, not the deconstructing or rest syntax
const json = [{...}, {...}];
const user = json.find(f => f.id === "the-id-here");
Related
I'm bumbling my way through adding a back-end to my site and have decided to get acquainted with graphQL. I may be structuring things totally the wrong way, however from following some tutorials I have a React front-end (hosted on Vercel), so I have created an api folder in my app to make use of Vercel's serverless functions. I'm using Apollo server and I decided to go with Fauna as my database.
I've successfully been able to return an entire collection via my API. Now I wish to be able to return the collection sorted by my id field.
To do this I created an index which looks like this:
{
name: "sort_by_id",
unique: false,
serialized: true,
source: "my_first_collection",
values: [
{
field: ["data", "id"]
},
{
field: ["ref"]
}
]
}
I then was able to call this via my api and get back and array, which simply contained the ID + ref, rather than the associated documents. I also could only console log it, I assume because the resolver was expecting to be passed an array of objects with the same fields as my typedefs. I understand I need to use the ref in order to look up the documents, and here is where I'm stuck. An index record looks as follows:
[1, Ref(Collection("my_first_collection"), "352434683448919125")]
In my resolvers.js script, I am attempting to receive the documents of my sorted index list. I've tried this:
async users() {
const response = await client.query(
q.Map(
q.Paginate(
q.Match(
q.Index('sort_by_id')
)
),
q.Lambda((ref) => q.Get(ref))
)
)
const res = response.data.map(item => item.data);
return [... res]
}
I'm unsure if the problem is with how I've structured my index, or if it is with my code, I'd appreciate any advice.
It looks like you also asked this question on the Fauna discourse forums and got an answer there: https://forums.fauna.com/t/unable-to-return-a-list-of-documents-via-an-index/3511/2
Your index returns a tuple (just an array in Javascript) of the data.id field and the ref. You confirmed that with your example result
[
/* data.id */ 1,
/* ref */ Ref(Collection("my_first_collection"), "352434683448919125")
]
When you map over those results, you need to Get the Ref. Your query uses q.Lambda((ref) => q.Get(ref)) which passes the whole tuple to Get
Instead, use:
q.Lambda(["id", "ref"], q.Get(q.Var("ref")))
// or with JS arrow function
q.Lambda((id, ref) => q.Get(ref))
or this will work, too
q.Lambda("index_entry", q.Get(q.Select(1, q.Var("index_entry"))))
// or with JS arrow function
q.Lambda((index_entry) => q.Get(q.Select(1, index_entry)))
The point is, only pass the Ref to the Get function.
I'm trying to get object data from firestore
the problem is that although I saved the data as
command, damage, frame, state, way
when I get the data from firestore in React,
the order of the object is shuffled.
For example,
frame, range, command, damage, hitframe
range, hitframe, frame, command, damage,
etc...
I want it to be orderd as command, damage, frame, state, way
Here’s how you can sort an object by its keys/properties, alphabetically:
<script>
const unordered = {
'frame': 'foo',
'range': 'bar',
'command': 'baz',
'damage': 'hit',
'hitframe': 'no'
};
console.log(JSON.stringify(unordered));
// → '{'frame': 'foo', 'range': 'bar','command': 'baz','damage': 'hit','hitframe': 'no'}'
const ordered = Object.keys(unordered).sort().reduce(
(obj, key) => {
obj[key] = unordered[key];
return obj;
},
{}
);
console.log(JSON.stringify(ordered));
// → '{"command":"baz","damage":"hit","frame":"foo","hitframe":"no","range":"bar"}'
</script>
In this way, you will be able to get your objects in alphabetical order. Mention if you need anything else.
The data is saved as array and as such sorted by the array index. I would recommend thatyou just sort the data on client side when receiving it using the JavaScript sort array.
I want to get a list of people that have the same tags as the user.
For that I need to use a react native fetch and the entity framework.
I also tried some raw sql with EF, but couldn't make it work, just don't know how.
I have two fetches. Both return a typical JSON object array. So I'm doing this:
var users = db.Users
.Include("TagUsers")
.Where(u => u.TagUsuario.Any(t => tags.Contains(t.idTag))).ToList();
The tags variable is an object array from a React Native Fetch, which in my C# function is of the type IList<>long.
The problem is that if this array have one element, like this const tags = [1]; or from the fetch like this
{0}
Tags:
idTag: 1
Name: "MyTag"
I can return the people with this tag, but if I do like this const tags = [1, 2]; or
{0}
Tags:
idTag: 1
Name: "MyTag"
{1}
Tags:
idTag: 2
Name: "AnotherTag"
It returns nothing on my LINQ request.
But if I do something like this on my C# function:
IList<>long tags = new List<>long();
tags.Add(1);
tags.Add(2);
It works perfectly.
The problem here is that the object array from the fetch is not "compatible" with the LINQ statement (Any, Contains). So I am in search of an alternative.
What do I have to do?
Change the IList parameter? I'm using that because accepts null without crashing.
Change the LINQ?
Use Raw SQL?
Maybe some conversion to get only an int array with the tags, not an object one.
Thanks for any tips and solutions.
Can you try to get the idTags from tags and use it as below.
var idTags = tags.Select(t => t.idTag);
var users = db.Users
.Include("TagUsers")
.Where(u => u.TagUsuario.Any(t => idTags.Contains(t.idTag))).ToList();
I have a large JSON file which contains an array. I am using Firebase for my app's backend and I want to use FirebaseArray to store the data.
It is simple to create a FirebaseArray from my Angular app and add data to it, but the nature of my app is that I have fetched data which I need to first import into Firebase somehow.
On the Firebase website the only option for importing is from a JSON. When I import my JSON file, the result is an object with numerical keys, which I realize is like an array, but has a major issue.
{
"posts": {
"0": {
"id": "iyo0iw",
"title": "pro patria mori"
},
"1": {
"id": "k120iw",
"title": "an english title"
},
"2": {
"id": "p6124w",
"title": "enim pablo espa"
}
}
}
Users are able to change the position of items, and the position of an item is also how items are uniquely identified. With multiple users this means the following problem can occur.
Sarah: Change post[0] title to "Hello everyone"
Trevor: Swap post[1] position with post[2]
Sarah: Change post[1] title to "This is post at index 1 right?"
If the following actions happen in a short space of time, Firebase doesn't know for sure what Sarah saw as post[1] when they changed the title, and can't know for sure which post object to update.
What I want is a way to import my JSON file and have the arrays become FirebaseArrays, not objects with numerical keys, which are like arrays and share the issue described above.
What you imported into your database is, in fact, an array. Firebase Realtime Database only really represents data as a nested hierarchy of key/value pairs. An array is just a set of key/value pairs where the the keys are all numbers, typically starting at 0. That's exactly the structure you're showing in your question.
To generate the sort of data that would be created by writing to the database using an AngularFire FirebaseArray, you would need to pre-process your JSON.
Firebase push IDs are generated on the client and you can generate one by calling push without arguments.
You could convert an array to an object with Firebase push ID keys like this:
let arr = ["alice", "bob", "mallory"];
let obj = arr.reduce((acc, val) => {
let key = firebase.database().ref().push().key;
acc[key] = val;
return acc;
}, {});
Realmswift Data Model
class User {
let id = RealmOptional<Int>()
dynamic var name = ""
let albums = List<Album>()
override static func primaryKey() -> String {
return "id"
}
}
class Album: Object {
dynamic albumName = ""
let imageIDs = List<ImageID>()
}
class ImageID: Object {
let imageId = RealmOptional<Int>()
}
JSON data
{
"10001": {
"id" : 10001,
"name": "John",
"album": {
"albums": [
{
"albumName": "Summer1999",
"imageIds": [11223, 11224, 11227]
},
{
"albumName": "Xmas1999",
"imageIds": [22991, 22997]
},
{
"albumName": "NewYear2000",
"imageIds": [5556, 776, 83224, 87543]
}
]
}
}
}
I have the above json data and I m using SwiftyJSON to parse the data then write into realm. Everything is working great except for checking and updating of data (for example imageIds on json file have changed).
Question: How do i compare the JSON arrays and RealmSwift List to determine it any updates need to be written into the database?
You can take advantage of your primary key here. As Realm Swift documentation states:
Creating and Updating Objects With Primary Keys: If your model class
includes a primary key, you can have Realm intelligently update or add
objects based off of their primary key values using
Realm().add(_:update:).
So (I assume that you get the JSON from some kind of a request (REST etc.) and then parse it with SwiftyJSON to create a 'User' object) you can treat the new 'User' object as regular new 'User' and try to add it to Realm as usual, but 'update' parameter must be 'true'. If there already was a user with the id of the 'User' object you are trying to add, it will just update the existing 'User' i.e. changing its modified values from the new 'User' created by parsing new JSON data. This might look something like this:
//Parse JSON and create a 'User'
let newUserFromJSON = parseAndCreateUserFromJSON(JSONData)
let realm = try! Realm()
do {
try realm.write {
realm.add(newUserFromJSON, update: true)
}
} catch let error as NSError {
print("error writing to realm: \(error.description) & \(error)")
} catch {
print("error writing to realm: UNKNOWN ERROR")
}
I'm afraid there's probably no easy answer to this. There's no mechanism in Realm to compare the contents of a Realm Object to an external object to see if their data matches. You would need to iterate through each object in the Realm object and manually compare it.
This wouldn't be too much code to write (Since you can get a list of all of the Realm file's properties via the objectSchema property of Realm objects, and then use key-value coding to pull them out in a single for loop), but would still be a fair amount of overhead to perform the compare.
That being said, if what you're wanting to look at is just certain properties that might change (i.e. like you said, just the imageIDs property), then you could easily just check the values you need.
What bcamur has suggested is definitely the quickest (And usually preferred for JSON handing) solution here. As long as you've set your primary key properly, you can call Realm.add(_:, update:) with update set to true to update the object.
Please keep in mind this doesn't merge the new data with what was already in Realm; it'll completely overwrite the old object with the new values, which if it sounds like your ID numbers are changing, would be the best course of action.