Can i send array with null to GraphQL Nest.js resolver? - javascript

Can i do that?
I use it in input type:
#Field(() => [String], {
nullable: true,
})
date: string[];
And when i send on in date key, null on some array index, i got an error. Example:
date: ["2023-02-13 00:00:00", null, null, "2023-02-13 00:00:00"] ->
Error: Expected value of type "String!", found null."
Can i send an array with null in some position?

Related

Filtering for activity with certain property

In discordjs, I'm trying to read a users presence and then do "If one of presences stated (A user can have Spotify and a game simultaneously as an example) has a name of, say Spotify, in it's properties, do something". My code is:
let uset = msgMention.presence.activities
if (uset.filter(game => game.name == 'Spotify')){
//something
}
Since multiple games return multiple items in an array (seen below)
[
Activity {
name: 'Spotify',
type: 'LISTENING',
url: null,
details: null,
state: 'NO',
applicationID: 'NO',
timestamps: no,
party: null,
assets: RichPresenceAssets {
largeText: null,
smallText: null,
largeImage: 'no',
smallImage: null
},
syncID: no,
flags: ActivityFlags { bitfield: 1 },
emoji: null,
createdTimestamp: no
},
Activity {
name: 'Visual Studio Code',
type: 'PLAYING',
url: null,
details: 'Editing league.js',
state: 'Workspace: Vibin-Tachanks',
applicationID: '383226320970055681',
timestamps: { start: 2021-12-04T18:35:34.918Z, end: null },
party: null,
assets: RichPresenceAssets {
largeText: 'Editing a JAVASCRIPT file',
smallText: 'Visual Studio Code',
largeImage: '808841241142755358',
smallImage: '565945770067623946'
},
syncID: undefined,
flags: ActivityFlags { bitfield: 0 },
emoji: null,
createdTimestamp: 1638645018501
}
]
how can I make this if statement work to filter out this returned array and only keep Spotify in it, and then access the name (or any property) of said filtered item. yes, i do have detecting presences working with intents and such so I know I've gotten that far, it's just filtering with an if (Also no just means I dont want to show whats in it)
You could just use this filter that you used inside a variable and as the condition of the if statement you could just check if it's different than empty array "[]".
Doing this way you can use the values inside the variable if you have any.

Unable to update Mongoose Nested Array

I've spent a day going through Mongoose documentation and posts on here and while I'm almost certain I have the code as prescribed in all those solved posts I simply cannot get my code to work. :(
The schema is relatively complex but by no means as complex as I've seen:
const hrUserSchema = new mongoose.Schema({
username: String,
displayName: String,
school: String,
leaveAuthoriser: String,
holidayLeft: Number,
holidayAllowed: Number,
discretionaryDays: Number,
emailAddress: String,
termTimeOnly: Boolean,
noOfAdditionalContractedDays: Number,
noOfAdditionalContractedDaysLeft: Number,
teachingStaff: Boolean,
employStartDate: String,
notes: String,
loginAttempts: Number,
lineManages: [{
staffName: String
}],
bookedHoliday: [{
dateEntered: String,
startDate: String,
endDate: String,
daysTaken: Number,
status: String,
approvedBy: String,
leaveType: String,
declineReason: String
}],
additionalContractedDays: [{
acdDateEntered: String,
acdStartDate: String,
acdEndDate: String,
acdDaysTaken: Number,
acdStatus: String,
acdApprovedBy: String,
acdDeclineReason: String
}],
perfMan: [{
year: Number,
selfReview: {
sref1: String,
sref2: String,
sref3: String,
sref4: String,
sref5: String,
status: String,
dateStarted: String,
dateCompleted: String,
signedOff: Boolean
},
stage1: {
objectives : [
{
objective: String,
objectiveLinkToSchoolTeam: String,
objectiveProgress: Boolean
}
],
personalDevelopment: String,
resourcesTraining: String,
appraiserSignOff: Boolean,
appraiseeSignOff: Boolean
},
stage2: {
feedback: String,
appraiserSignOff: Boolean,
appraiseeSignOff: Boolean
},
stage3: {
feedback: String,
appraiserSignOff: Boolean,
appraiseeSignOff: Boolean
}
}]
});
Basically I want to update perfMan.stage1.objectives.objectiveProgress, example of what data in that might look like is:
"perfMan" : [
{
"_id" : ObjectId("60cb502631dcea3eaaae6853"),
"selfReview" : {
"sref1" : "I have no strength",
"sref2" : "No developments",
"sref3" : "None I'm brill",
"sref4" : "The department has no aims",
"signedOff" : true
},
"stage1" : {
"objectives" : [
{
"_id" : ObjectId("60cb502631dcea3eaaae6854"),
"objective" : "Objective is pants",
"objectiveLinkToSchoolTeam" : "I hate objectives!",
"objectiveProgress" : false
},
{
"_id" : ObjectId("60cb502631dcea3eaaae6855"),
"objective" : "My second Objectoves",
"objectiveLinkToSchoolTeam" : "My Second reasons",
"objectiveProgress" : false
}
],
"personalDevelopment" : "My personal Development",
"resourcesTraining" : "My Resources"
},
"stage2" : {
"feedback" : "Keep working HARD",
"appraiserSignOff" : true
},
"stage3" : {
"feedback" : "Yoy've done really well",
"appraiserSignOff" : true
},
"year" : NumberInt(2021)
}
]
I've read about and tried to implement this by using arrayFilters which to me seems to exactly what I want, I've checked my Mongoose version (hosted) and it's 4.4.6 so I'm easily running above 3.6 which I think is what's needed.
My current code looks like this, I've confirmed the find is getting the right data:
HRUser.findOneAndUpdate(
{"username": username},
{"$set": {"perfMan.$[perfMan].stage1.objectives.$[objectives].objectiveProgress" : true}},
{"arrayFilters" : [{ "perfMan._id": ObjectId("" + perfmanID + "") },{ "objectives._id": ObjectId("" + objectiveID + "") }]}
),
function (err, response) {
console.log(err)
console.log(response);
if (!err) {
res.send("Successfully updated staff member details.");
} else {
res.send(err);
}
};
If somebody could spot my obviously glaring error I would be for ever grateful!
Thanks
After not looking at a screen all weekend and reading through the documentation for the billionth time I decided to change tack! I can't see any limitations on the number of arrayFilters, or for that matter objectID use within them, and I'm 99% certain both object IDs are correct but, after changing the code to the below, basically using a mix of a positional operator $ based on the search of the same first objectID AND an arrayFilter element it's now working! Code below:
HRUser.findOneAndUpdate({
perfMan: {
$elemMatch: {
_id: ObjectId("" + perfManID + "")
}
}
},
{"$set": {"perfMan.$.stage1.objectives.$[objectives].objectiveProgress" : false}},
{"arrayFilters" : [{ "objectives._id": ObjectId("" + objectiveID + "") }]},
function (err, response) {
console.log(err)
console.log(response);
});

How to Wrap a REST API POST nested object with GraphQL

I am trying to figure out how to wrap mutate a nested object with graphql mutations, if possible. For instance I have the following schema:
type Equipment{
assetId: ID
assetName: String
assetTag: String
createdAt: String
updatedAt: String
available: Boolean
category: Category
purchaseAt: String
purchaseCost: Float
serial: String
notes: String
}
type Category{
categoryId: ID,
name: String
}
type Mutation {
equipamento( e: EquipmentInput): Equipment
}
input EquipmentInput{
assetName: String
assetTag: String
available: Boolean
purchaseAt: String
category: CategoryInput
purchaseCost: Float
serial: String
notes: String
}
input CategoryInput{
categoryId: ID
name : String
}
This is the POST call on REST. This call works
{
"assetName": "Dell Laptop E5570",
"assetTag": "A0001",
"available": false,
"category":{
"categoryId": 1
} ,
"purchaseAt": "2018-09-10",
"purchaseCost": 1200.00,
"serial": "Serial",
"notes": "Novo"
}
I am trying to do a equivalent on GraphQL using graphql-yoga, but category is a nested object and the create call fail on REST service.
equipamento: (parent, args) => {
const equipment = {
assetName: args.e.assetName,
assetTag: args.e.assetTag,
available: args.e.available,
category: args.e.category.categoryId,
purchaseAt: args.e.purchaseAt,
purchaseCost: args.e.purchaseCost,
serial: args.e.serial,
notes: args.e.notes
}
return fetch(`${equipmentURL}/`, {
method: 'POST',
body: JSON.stringify(equipment),
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json());
}```
Console Log for the GraphQL is
```{"assetName":"Dell Laptop E5570","assetTag":"A0001","available":false,"category":1,"purchaseAt":"2018-09-10","purchaseCost":1200,"serial":"Serial","notes":"Novo"}```
So the question is, how can i format my mutation to have nested object?

Mongoose populate returns empty array but returns data without populate

I am trying to fetch appointments and populate them with user details and doctor details. I have a schema like this
let appointmentSchema = new Schema({
reason: String,
start: DateType,
end: DateType,
appointmentStamp: Number,
userId: {
type: ObjectId,
ref: 'User'
},
doctorId: {
type: ObjectId,
ref: 'Doctor'
},
approved: Boolean,
held: Boolean,
timeOfAcceptance: Number,
createdOn: { type: Number, default: (new Date().getTime()) },
updatedAt: Mixed
}, {runSettersOnQuery: true})
And on running
Appointment.find({userId: authId}).populate('userId doctorId').exec()
I get an empty array
but
Appointment.find({userId: authId}).exec()
return all the appointments for that user with the userId supplied in find
what am I missing out
Here is a sample appointment
{
"_id": "5a0d424079191657fca9e853",
"reason": "Say Hello",
"approved": false,
"held": false,
"doctor": "5a0add9b577d7916187cd9f2",
"patient": "59f5df20a3071554c5f843e1",
"appointmentStamp": 1510927380000,
"__v": 0,
"createdOn": 1510817910134
}
I tried this and it worked, don't know why
patient: {
type: String,
ref: 'patient'
},
doctor: {
type: String,
ref: 'doctor'
}
instead of ObjectId I used type of String
then the query be like
Appointment.find({patient: authId, canceled: false})
.populate('patient doctor').exec()

Getting the same Object back when using the array.filter with a valid condition

I am trying to get the value of the 'text' key in a Json object that I get from a GET request to twitter via the twit library.
Im trying to use the filter function on the array because i wanna do functional programming.
I can use the json object inside a callback function on the T.get function:
const gotData = function(err, data, response) {
console.log(data)
}
T.get('search/tweets', params , gotData)
Then I want to filter only the value on the text key on each of the statuses, which is an array of objects
So i tried this:
let results = data.statuses.filter(
function(result){ return result.hasOwnProperty('text')
})
But I get back the same data.statuses back... ?
I want to get only the value of the text keys on the objects, what im I doing wrong ?
this is my whole code:
const Twit = require('twit')
const config = require('./config')
const T = new Twit(config)
let params = { q: 'drum', count: 2 }
const gotData = function(err, data, response) {
let results = data.statuses.filter(function(result){ return result.hasOwnProperty('text')})
console.log(results)
}
T.get('search/tweets', params , gotData)
And this a sample of the Json response i get, which corresponds to the data on the gotData function:
{ statuses:
[ { created_at: 'Sun May 07 11:35:16 +0000 2017',
id: 861182642888343600,
id_str: '861182642888343552',
text: '#was_going \nEvery hunk bore seven drums,\nEvery drum owned seven drums…',
truncated: false,
entities: [Object],
metadata: [Object],
source: 'Cheap Bots, Done Quick!',
in_reply_to_status_id: 861181362954489900,
in_reply_to_status_id_str: '861181362954489856',
in_reply_to_user_id: 795028044758949900,
in_reply_to_user_id_str: '795028044758949888',
in_reply_to_screen_name: 'was_going',
user: [Object],
geo: null,
coordinates: null,
place: null,
contributors: null,
is_quote_status: false,
retweet_count: 0,
favorite_count: 0,
favorited: false,
retweeted: false,
lang: 'en' },
{ created_at: 'Sun May 07 11:35:09 +0000 2017',
id: 861182610596405200,
id_str: '861182610596405248',
text: 'Would you rather have Data storage or A pedal assembly for a bass drum or high hat cymbals?',
truncated: false,
entities: [Object],
metadata: [Object],
source: 'Cheap Bots, Done Quick!',
in_reply_to_status_id: null,
in_reply_to_status_id_str: null,
in_reply_to_user_id: null,
in_reply_to_user_id_str: null,
in_reply_to_screen_name: null,
user: [Object],
geo: null,
coordinates: null,
place: null,
contributors: null,
is_quote_status: false,
retweet_count: 0,
favorite_count: 0,
favorited: false,
retweeted: false,
lang: 'en' } ],
search_metadata:
{ completed_in: 0.034,
max_id: 861182642888343600,
max_id_str: '861182642888343552',
next_results: '?max_id=861182610596405247&q=drum&count=2&include_entities=1',
query: 'drum',
refresh_url: '?since_id=861182642888343552&q=drum&include_entities=1',
count: 2,
since_id: 0,
since_id_str: '0' } }
You just check if theres a text property. You might also want to map it to that property:
let results = data.statuses.filter(
result=>result.hasOwnProperty('text')
).map(result=>result.text);
http://jsbin.com/niwezocuhu/edit?console
Or if you take care on performance ( O(n) instead of O(n+n*r)):
let results= data.statuses.reduce((arr,result)=>(result.text&&arr.push(result.text)&&false)||arr,[]);

Categories

Resources