I am trying to sideload relationship data from one API call. I have a my two models setup like so:
Contest Model (child, belongsTo):
import Model, { attr, belongsTo } from '#ember-data/model';
export default class ContestModel extends Model {
#attr('date') createdAt;
#attr('string') description;
#belongsTo('brand', { inverse: 'contests' }) brand;
}
Brand Model (parent, hasMany):
import Model, { attr, hasMany } from '#ember-data/model';
export default class BrandModel extends Model {
#attr('date') createdAt;
#attr('string') name;
#hasMany('contest') contests;
}
I'm fetching via this line:
this.store.findRecord('contest', params.contest_id, { include: 'brand' });
This is the returned API payload:
{
"data": {
"type": "contest",
"id": 1,
"attributes": {
"body_json": [
{
"question": "what time is it?",
"answers": ["1PM", "2PM", "3PM", "4PM"]
},
{
"question": "which collection is this artwork from?",
"answers": ["botanical garden collection", "ghibli collection", "adventure collection", "swag collection"]
}
],
"created_at": "2021-05-23 18:00:00 -0700",
"description": "a good description goes here"
},
"relationships": {
"brand": {
"links": {
"self": "http://example.com/contests/2/relationships/brand" // not sure what this does
},
"data": { "type": "brand", "id": 2 }
}
},
"links": {
"self": "http://example.com/contests/2" // not sure how this is useful
},
"included": [
{
"id": 2,
"type": "brand",
"attributes": {
"created_at": "2021-05-23 20:00:00 -0700",
"name": "aloha vibe"
}
}
]
}
}
The issue here is that calling myContest.brand returns a Proxy object just like in this SO post.
Is my API payload incorrect or is something misconfigured for my models? Or something else? I'm on Ember 3.25.3
Update from comments: When I add async: false to the Ember Data query, I get an error after this line https://github.com/emberjs/data/blob/v3.25.0/packages/store/addon/-private/system/model/internal-model.ts#L705 due to toReturn.isEmpty being true. Did I not configure my API payload? Not sure what is wrong. It seems neither createdAt nor name is populated.
Found the bug! The data payload needs to be in this format:
{
"data": {
"type": "contest",
"id": 1,
"attributes": {
"body_json": [
{
"question": "what time is it?",
"answers": ["1PM", "2PM", "3PM", "4PM"]
},
{
"question": "which collection is this artwork from?",
"answers": ["botanical garden collection", "ghibli collection", "adventure collection", "swag collection"]
}
],
"created_at": "2021-05-23 18:00:00 -0700",
"description": "a good description goes here"
},
"relationships": {
"brand": {
"links": {
"self": "http://example.com/brands/2"
},
"data": { "type": "brand", "id": 2 }
}
},
"links": {
"self": "http://example.com/contests/2"
}
},
"included": [
{
"id": 2,
"type": "brand",
"attributes": {
"created_at": "2021-05-23 20:00:00 -0700",
"name": "aloha vibe"
}
}
]
}
I had nested the included within the data section but it should be at the top level with the data section. Now things are properly sideloaded and no extra API call is made :)
Related
I'm making a kanban task management app and I'm trying to remove a task with the _id: req.params.id which has the value of 62fa5ae05778ec97bc6ee23a. I tried the following:
const task = await Board.findOneAndUpdate(
{
"columns.tasks._id": req.params.id,
},
{ $pull: { "columns.$.tasks.$._id": req.params.id } },
{ new: true }
);
But I get the error Too many positional (i.e. '$') elements found in path'columns.$.tasks.$._id'
I searched for a while and came across arrayFilters from the docs but I'm struggling a lot to understand how to implement it for this particular need.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{
"title": "Task Four",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23b"
},
{
"name": "do homework",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23c"
}
],
"_id": "62fa5ae05778ec97bc6ee23a"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v": 0
}
You need to use $[] positional operator in order to pull from the nested array. Try running this query:
db.Board.updateOne({
"_id" : "62fa5aa25778ec97bc6ee231",
}, {
$pull: { 'columns.$[].tasks': { '_id': '62fa5ae05778ec97bc6ee23a' } }
});
I get the following error on a react component. I thought I had set a unique key when I look in graphQL playground explorer the id I am grabbing is unique for each element. So I am not sure why I am getting this error. I read that the elements inside my also need a key which I thought wasn't the case. Hopefully someone can help.
Error
Warning: Each child in a list should have a unique "key" prop.
GraphQL Query
query MyQuery {
allDatoCmsPricing {
edges {
node {
id //This was orignally there when I posted
details {
id //This was missing that was my error which was answered
task
}
}
}
}
}
GraphQL Result
{
"data": {
"allDatoCmsPricing": {
"edges": [
{
"node": {
"details": [
{
"id": "DatoCmsItem-1919839-en",
"task": "Client Consultation"
},
{
"id": "DatoCmsItem-1919840-en",
"task": "S.M.A.R.T Goal Setting"
},
{
"id": "DatoCmsItem-1919841-en",
"task": "Fitness Assessment"
},
{
"id": "DatoCmsItem-1919842-en",
"task": "Client Centered Exercises"
},
{
"id": "DatoCmsItem-1919843-en",
"task": "1-2 Sessions per week"
}
]
}
},
{
"node": {
"details": [
{
"id": "DatoCmsItem-1927942-en",
"task": "Client Consultation"
},
{
"id": "DatoCmsItem-1927943-en",
"task": "S.M.A.R.T Goal Setting testing breaking line"
},
{
"id": "DatoCmsItem-1927945-en",
"task": "Fitness Assessment"
},
{
"id": "DatoCmsItem-1927946-en",
"task": "Client Centered Exercises"
},
{
"id": "DatoCmsItem-1927947-en",
"task": "Injury Prevention"
},
{
"id": "DatoCmsItem-1927948-en",
"task": "Nutrition Advice"
},
{
"id": "DatoCmsItem-1927949-en",
"task": "Program Design"
},
{
"id": "DatoCmsItem-1927950-en",
"task": "Corrective Exercises"
},
{
"id": "DatoCmsItem-1927951-en",
"task": "3 or more Sessions per week"
}
]
}
},
{
"node": {
"details": [
{
"id": "DatoCmsItem-1927866-en",
"task": "Client Consultation"
},
{
"id": "DatoCmsItem-1927867-en",
"task": "S.M.A.R.T Goal Setting"
},
{
"id": "DatoCmsItem-1927868-en",
"task": "Fitness Assessment"
},
{
"id": "DatoCmsItem-1927869-en",
"task": "Client Centered Exercises"
},
{
"id": "DatoCmsItem-1927870-en",
"task": "Injury Prevention"
},
{
"id": "DatoCmsItem-1927872-en",
"task": "Nutrition Advice"
},
{
"id": "DatoCmsItem-1927873-en",
"task": "2-3 Sessions per week"
}
]
}
}
]
}
}
}
Component
{data.allDatoCmsPricing.edges.map(({ node: pricing }) => (
<div key={pricing.id} >
<ul className="details-list">{pricing.details.map(detailEntry => {
return <ListItem key={detailEntry.id}><span>{detailEntry.task}</span>
</ListItem>
})}</ul>
</div>
...
It looks like pricing.id is undefined. It's represented by node.id in your data, but you only have a details property present. Your graphql query reflects this. Adding id to the query should resolve the error:
query MyQuery {
allDatoCmsPricing {
edges {
node {
id # <--- Added this field
details {
id
task
}
}
}
}
}
I am trying to insert/update data with the javascript elasticsearch client, but I am getting the error:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Malformed action/metadata line [1], expected a simple value for field [_data] but found [START_OBJECT]"
}
],
"type": "illegal_argument_exception",
"reason": "Malformed action/metadata line [1], expected a simple value for field [_data] but found [START_OBJECT]"
},
"status": 400
}
This is the data that is being sent
esclient.bulk({
body: [
{
"index":
{
"_index":"myindex",
"_type":"movie",
"_id":"1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
"_data":
{
"title":"Title 2",
"description":"This should be updated with this new data.",
"score":1,
"suggest_title":"Title 2",
"img":"http://url.to.image/img.jpeg",
"genres":["Comedy"],
"release":"2015-01-07T23:00:00.000Z",
"language":"EN",
"provider":
{
"id":"InstaFilmFlixify",
"url":"http://www.InstaFilmFlixify.com/play?id=238412"
}
}
}
}
]
})
It appears as this code generates the following request to ES:
-> POST http://docker.me:9200/_bulk
{
"index": {
"_index": "myindex",
"_type": "movie",
"_id": "1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
"_data": {
"title": "Title 2",
"description": "This should be updated with this new.",
"score": 1,
"suggest_title": "Title 2",
"img": "http://url.to.image/img.jpeg",
"genres": [
"Comedy"
],
"release": "2015-01-07T23:00:00.000Z",
"language": "EN",
"provider": {
"id": "InstaFilmFlixify",
"url": "http://www.InstaFilmFlixify.com/play?id=238412"
}
}
}
}
What am I doing wrong? What is happening? Can this possibly be a bug in ES / the ES adapter.
Elasticsearch version 2.1
I haven't seen the "_data" parameter before. Where did you get the idea to use that?
Take a look at the docs for the js client.
Anyway, this should work for you:
esclient.bulk({
body: [
{
"index":
{
"_index":"myindex",
"_type":"movie",
"_id":"1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
}
},
{
"title":"Title 2",
"description":"This should be updated with this new data.",
"score":1,
"suggest_title":"Title 2",
"img":"http://url.to.image/img.jpeg",
"genres":["Comedy"],
"release":"2015-01-07T23:00:00.000Z",
"language":"EN",
"provider":
{
"id":"InstaFilmFlixify",
"url":"http://www.InstaFilmFlixify.com/play?id=238412"
}
}
]
})
I have 2 distinct data types in the same couchdb database, message and user. They look like follows:
// message
{
"_id": "test__032142f981b1bddd00bb9a0161688480",
"_rev": "8-d1b19caabac334c4b9e9eb1f0b0b8986",
"created": "2011-12-27T23:48:17.940699Z",
"text": "Omnis quam nesciunt dolor quaerat.",
"author_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"type": "message",
"subject": "Some text"
"recipients": [
"user id 1",
"user id 2",
]
}
//user
{
"_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"_rev": "12-88206492cc5274248aa5a64ff6a49b9a",
"type": "user",
"profile": {
"callname": "User name",
"fullname": "User name",
"profile_text": "Blah blah",
"urls": [
{
"url": "http://www.example.org",
"description": "CV, Blog, Pictures, Research, Links",
"label": "Homepage"
}
],
"profile_image_url": "http://localhost:5000/static/img/profiles/2e38f9fdd9e458eb4db0e7bb3b8e9576.jpg"
},
"registration_date": "2014-08-14T20:07:28Z",
"verified": "none",
"preferences": {
"lang": "en"
},
"last_login": "2014-08-14T20:07:28Z",
"email": "user#example.org"
}
Out of reasons, inlining is not a possibility in this case. What I want now is to get a list of all messages with the author object included (Like SQL SELECT * FROM messages JOIN users on message.author_id = message.id).
I read this two articles:
http://www.cmlenz.net/archives/2007/10/couchdb-joins
http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
So I wanted to use include_docs=true and then a list to format it nicely. My messages map function:
function(doc) {
if (doc.type == 'message') {
emit(doc._id, {_id: doc.author_id, entity: doc});
}
}
I call this using the URL http://localhost:5984/dedri/_design/dedri/_view/messages?include_docs=true. But I get this, with doc: null:
{
"total_rows": 34,
"offset": 0,
"rows": [
{
"id": "test__032142f981b1bddd00bb9a0161688480",
"key": "test__032142f981b1bddd00bb9a0161688480",
"value": {
"_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"entity": {
"_id": "test__032142f981b1bddd00bb9a0161688480",
"_rev": "8-d1b19caabac334c4b9e9eb1f0b0b8986",
"created": "2011-12-27T23:48:17.940699Z",
"text": "Omnis quam nesciunt dolor quaerat.",
"version": "0.1",
"author_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"type": "message",
"subject": "Some text"
}
},
"doc": null
},
...
I don't know what to do anymore. There is no editing or deleting done in the map function. Is this a problem of mine or a bug?
Try change your map js to a simpler form for debugging, e.g.
function(doc) {
if (doc.type == 'message') {
// emit(doc._id, {_id: doc.author_id, entity: doc});
emit(doc._id, { '_id': doc.author_id });
}
}
I have a question about the Graph API.
I use Javascript for the API and make a little test website ,where you can log in ,look for new messages and write a new status.
My problem is that I can't get the messages or the thread.
FB.api('/me/inbox',function(response) { alert(response.id); } ); don't work.
Have somebody an example for getting the messages in the inbox??
Thanks
The /me/inbox request requires that you have the read_mailbox permission granted.
Once you've got that, the /me/inbox request will return an array of Thread's, which will look something like this;
{
"data": [
{
"id": "1126884978255",
"from": {
"name": "Someone's Name",
"id": "34723472"
},
"to": {
"data": [
{
"name": "Someone's Name",
"id": "34723472"
},
{
"name": "Matt Lunn",
"id": "560914724"
}
]
},
"message": "Testing the one-ness.",
"updated_time": "2012-01-31T12:13:00+0000",
"unread": 0,
"unseen": 0,
"comments": {
"data": [
{
"id": "1126884978255_6769",
"from": {
"name": "Someone's Name",
"id": "34723472"
},
"message": "£140!?",
"created_time": "2012-01-31T11:33:15+0000"
},
{
"id": "1126884978255_6771",
"from": {
"name": "Matt Lunn",
"id": "560914724"
},
"message": "^^ month in advance as well",
"created_time": "2012-01-31T11:33:26+0000"
}
]
},
"type": "thread"
}
],
"summary": {
"unseen_count": 0,
"unread_count": 21,
"updated_time": "2012-01-31T13:19:31+0000"
}
}
So depending which ID you're after, you'll have to do;
for (var i=0;i<response.data.length;i++) {
var thread = response.data[i];
for (var j=0;j<thread.comments.data.length;j++) {
var comment = thread.comments.data[j];
console.log(comment.message);
}
}
Hopefully you get the idea...