I want to run a single query with multiple mutations, but I need to reference the data from a previous mutations is that possible?
mutation {
venue1: createVenue(data: { name: "Test Venue 1", active: true }) {
id
}
layout1: createLayout(
data: { name: "Test Layout 1", active: true, venue: { connect: (I WANT TO USE venue1) } }
) {
id
}
}
This is a over-simplification of what I'm trying to do, I'll need to use a single query to seed a DB for testing purposes, and using create instead of connect won't be enough because there are required relations and elements which require multiple relations, so it need to be lineal to fill all of those relations.
Related
I need to retrieve just some columns of relations in typeorm query.
I have an entity Environment that has an relation with Document, I want select environment with just url of document, how to do this in typeorm findOne/findAndCount methods?
To do that you have to use a querybuilder, here's an example:
return this.createQueryBuilder('environment') // use this if the query used inside of your entity's repository or getRepository(Environment)...
.select(["environment.id","environment.xx","environment.xx","document.url"])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getOne();
Sorry I can't add comment to post above. If you by not parsed data mean something like "environment.id" instead of "id"
try this:
return this.createQueryBuilder("environment")
.getRepository(Environment)
.select([
"environment.id AS id",
"environment.xx AS xx",
"document.url AS url",
])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getRawOne();
Here is the code that works for me, and it doesn't require using the QueryBuilder. I'm using the EntityManager approach, so assuming you have one of those from an existing DataSource, try this:
const environment = await this.entityManager.findOne(Environment, {
select: {
document: {
url: true,
}
},
relations: {
document: true
},
where: {
id: environmentId
},
});
Even though the Environment attributes are not specified in the select clause, my experience is that they are all returned in the results, along with document.url.
In one of the applications that I'm working on, I have the need to bring back attributes from doubled-nested relationships, and I've gotten that to work in a similar way, shown below.
Assuming an object model where an Episode has many CareTeamMembers, and each CareTeamMember has a User, something like the code below will fetch all episodes (all attributes) along with the first and last name of the associated Users:
const episodes = await this.entityManager.find(Episode, {
select: {
careTeamMembers: {
id: true, // Required for this to work
user: {
id: true,
firstName: true,
lastName: true,
},
}
},
relations: {
careTeamMembers: {
user: true,
}
},
where: {
deleted: false,
},
});
For some reason, I have to include at least one attribute from the CareTeamMembers entity itself (I'm using the id) for this approach to work.
I have done some work to do a deep comparison (via Underscore and diff) between two objects (actually a pre-save and post-save version of the same document) in order to isolate the section that is different after a save. Take this document structure as an example:
{
_id: 4d39fe8b23dac43194a7f571,
name: {
first: "Jane",
last: "Smith"
}
services: [
{
service: "typeOne",
history: [
{ _id: 121,
completed: true,
title: "rookie"
},
{ _id: 122,
completed: false,
title: "novice"
}
]
},
{
service: "typeTwo",
history: [
{ _id: 135,
completed: true,
title: "rookie"
},
{ _id: 136,
completed: false,
title: "novice"
}
]
}
]
}
If a new element is added to the history array I'm able to successfully parse out that change.
However, in addition to pulling out this changed section, I also want to be able to effectively walk up from history in order to find the value for service, because I also need to know which of the two services array elements actually changed. Is there a way I can do this with native es6 JavaScript?
If not, is there a library I can use to determine this? Right now I'm able to get the value for "service" via indexing:
if (diff.path[1] === 0) {
targetService = "typeOne";
} else if (diff.path[1] === 1) {
targetService = "typeTwo";
} else if (diff.path[1] === 2) {
targetService = "typeThree";
}
But from my understanding this isn't full proof, because there's no guarantee the order of elements within "services" couldn't change at some point. I suppose this indexing method could work if I could enforce the ordering of the elements within the services array. I'm just not sure if there's a way to do that (open to suggestions if it is possible).
deep-diff gives you the path to this change, something like this:
{
kind: 'N',
path: ['services', 1, 'history'],
// ... other properties
}
You can use this path to track the changed object:
tree.services[changes.path[1]].service // 'typeTwo'
I am trying to create a React/Redux app which lists books. Each book then has related books. I know I should structure my redux store in some sort of normalized fashion like so:
{
books: {
'book1id': {
title: 'Book 1',
author: 'Author 1',
relatedBooks: ['book2id', 'book3id']
},
'book2id': {
title: 'Book 2',
author: 'Author 2',
relatedBooks: ['book1id']
}
}
}
and load each book as necessary.
The issue is where to store loading/error data from the API requests? Some ideas I had were to create an object for every book such as
books: {
'book1id': {
isLoading: false,
error: null,
book: {
title: 'Book 1',
...
}
},
...
}
But that seems to detract slightly from the readability/intuitiveness of the state. Is there a better way to structure the state?
I structure my redux store so that it includes an entities object for all of my relational data and I store things specific to a page or a set of routes in separate parts of the state. My state tree might look something like this:
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
isLoading: false
}
}
Now I am keeping track of my relational state separate from the state of my UI components. I would not recommend trying to store a isLoading state in an individual entity since that entity may or may not exist. If you need more granular loading/error state on a per entity basis then rather on a set of entities you have a few options. The first option is keep a set of IDs that are currently loading. This is not a very practical solution because you can't track success or failure with an ID simply being in a set or not.
The next, better solution is to keep a map from ID to a status object that includes if an individual entity is loading, if it was successful or if it failed to load and what the errors were.
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
loading: {
book1: {
status: 'FAILED',
error: 'Network request failed.'
},
book2: {
status: 'SUCCESS',
},
book3: {,
status: 'IN_PROGRESS'
}
}
}
}
In summary, I find separating out your relational state into an entities child object while having page specific sections of state to be working quite well for me.
I want to implement a follow system between users.
For that, I want to display all of the 250 users of my app, then add a checkmark button next to the ones I already follow, and an empty button next to the ones I do not follow.
var usersRef = firebase.database().ref(‘/users’);
var followingRef = firebase.database().ref(‘/followingByUser’);
var displayedUsers = [];
// I loop through all users of my app
usersRef.once('value', users => {
users.forEach(user => {
// For each user, I check if I already follow him or not
followingRef.child(myUid).child(user.key).once('value', follow => {
if (follow.val()) {
// I do follow this user, follow button is on
displayedUsers.push({
name: user.val().name,
following: true
});
} else {
// I do not follow this user, follow button is off
displayedUsers.push({
name: user.val().name,
following: false
});
}
})
})
})
When doing that, I often (not always) get the following error: "Error: Firebase Database (4.1.3) INTERNAL ASSERT FAILED: sendRequest call when we're not connected not allowed."
Eventually, all the data is fetched, but after 10 seconds instead of 1 (without the error).
I do not believe it is an internet connection issue, as I have a very fast and stable wifi.
Is it a bad practice to nest queries like that?
If not, why do I get this error?
My data is structured as below:
users: {
userId1: {
name: User 1,
email: email#exemple.com,
avatar: url.com
},
userId2: {
name: User 2,
email: email#exemple.com,
avatar: url.com
},
...
}
followByUser: {
userId1: {
userId2: true,
userId10: true,
userId223: true
},
userId2: {
userId23: true,
userId100: true,
userId203: true
},
...
}
Your current database structure allows you to efficiently look up who each user is following. As you've found out it does not allow you to look who a user is follow by. If you also want to allow an efficient lookup of the latter, you should add additional data to your model:
followedByUser: {
userId2: {
userId1: true,
}
userId10: {
userId1: true,
},
userId223: {
userId1: true,
},
...
}
This is a quite common pattern in Firebase and other NoSQL databases: you often expand your data model to allow the use-cases that your app needs.
Also see my explanation on modeling many-to-many relations and the AskFirebase video on the same topic.
What Type of Relationship is needed below, and How Can I Leverage SailsjS/Waterline to Simplify My Find and Update Queries?
In my app, I have Lists (List-Model), Items (Item-Model), and Provisions (Provision-Model). The app's intention is to manage Inventory. As so, Items are discrete -- meaning, there can only be one of the same Item in the Items-collection (primaryKey is set on item.name). A single List shares a One-To-Many relationship with Items -- vicariously through Provisions. A Provision is simply a [discrete] Item's details for a given List. In this case, a Provision is only accessible using both a List-Id and and Item-Id (list.id + item.id === provision.compositePrimaryKey).
My issue is the complexity in dealing with find and update operations. With an alternative approach, I had just a Many-To-Many relationship between Lists and Items (with Items dominant) -- and this generated an Item upon List-Updates and aggregated Items with List.find(...).populate('items'). This was nearly ideal but I needed Provisions in the mix. Now (with the Schema below), the same relationship exists between Lists and Provisions -- List updates and 'populates' generate and aggregate a Provision with the correct list.id, but I was expecting Sails/Waterline to generate an Item-Model-Instance because Provision contains a item: { model: 'item' } attribute. Here is my current approach:
Provisions:
//api/models/Provision.js
module.exports = {
schema: true,
attributes: {
...
list: { model: 'list' },
item: { model: 'item' },
quantity: { type: 'integer' },
...
}
};
Lists:
//api/models/List.js
module.exports = {
schema: true,
attributes: {
...
items: { collection: 'provision', via: 'list' },
...
}
};
Items:
//api/models/Item.js
module.exports = {
schema: true,
attributes: {
...
name: { type: 'string', primaryKey: true }
lists: { collection: 'provision', via: 'item' },
inStock: { type: 'integer' },
...
}
};
I would like to generate a Provision -- if only through updating a list -- and have a discrete Item found or created automatically -- and hydrate an Item in the Provision-instance when performing a find on a List, as each List's Provision will have a model link to Item.
How can I do this, or is there a better design which I should employ?
Currently primaryKey must be id, look after sails hooks blueprint at actionUtil that primary key must be id field yet. So your Item.js should be
module.exports = {
schema: true,
attributes: {
...
// change it's column name if necessary fo your DB scheme
id: { type: 'string', unique: true, primaryKey: true, columnName: 'name' }
lists: { collection: 'provision', via: 'item' },
inStock: { type: 'integer' },
...
}
};
I don't pretty understand what and how do you want to approach. But using Lifescycle callbacks may help you. For example in your statement I would like to generate a Provision -- if only through updating a list -- and have a discrete Item found or created automatically, so use beforeUpdate, beforeCreate, etc. that meets your need.