I have this view in the playground:
But when I try to add another option to select, I hit CTRL + space and I see every single possible option, even the ones already selected.
How can I stop that from happening? In the dropdown I'd like to see only the options I still can select, not the ones already selected.
Here's my index.ts
const app = express();
(async () => {
const schema = await buildSchema({ resolvers: [ UserResolvers ] });
const server = new ApolloServer({ schema });
server.applyMiddleware({ app });
createConnection({
type: 'mysql',
...dbData,
entities: [
Availability,
Chat,
Meeting,
Message,
Offer,
Tag,
User,
],
synchronize: true,
logging: true,
})
.then(() => {
app.listen({ port: 4000 }, () => {
console.log(
`🚀 Server ready at http://localhost:4000${ server.graphqlPath }`,
);
});
})
.catch((error) => console.log(error));
})();
There is no option to change this behavior. You can open an issue in the GraphiQL repo (GraphQL Playground is effectively deprecated and will be merged into GraphiQL) to request this feature.
However, it's also unlikely that such a feature will ever be supported. Duplicate field names are perfectly valid in GraphQL. In addition, it's not uncommon to request the same field multiple times using a different alias and a different set of arguments for each instance of the field:
query {
activeUsers: users(isActive: true) {
...UserFragment
}
inactiveUsers: users(isActive: false) {
...UserFragment
}
}
In that context, omitting a field from the list of suggestions just because it was already included in the selection set doesn't really make sense.
Related
Let's say I have a very basic API with two sets of endpoints. One set queries and mutates properties about a User, which requires a username parameter, and one set queries and mutates properties about a Post, which requires a post ID. (Let's ignore authentication for simplicity.) I don't currently see a good way to implement this in a DRY way.
What makes the most sense to me is to have a separate Context for each set of routes, like this:
// post.ts
export async function createContext(
opts?: trpcExpress.CreateExpressContextOptions
) {
// pass through post id, throw if not present
}
type Context = trpc.inferAsyncReturnType<typeof createContext>;
const router = trpc
.router()
.query("get", {
resolve(req) {
// get post from database
return post;
},
});
// similar thing in user.ts
// server.ts
const trpcRouter = trpc
.router()
.merge("post.", postRouter)
.merge("user.", userRouter);
app.use(
"/trpc",
trpcExpress.createExpressMiddleware({
router: trpcRouter,
createContext,
})
);
This complains about context, and I can't find anything in the tRPC docs about passing a separate context to each router when merging. Middleware doesn't seem to solve the problem either - while I can fetch the post/user in a middleware and pass it on, I don't see any way to require a certain type of input in a middleware. I would have to throw { input: z.string() } or { input: z.number() } on every query/mutation, which of course isn't ideal.
The docs and examples seem pretty lacking for this (presumably common) use case, so what's the best way forward here?
This functionality has been added in (unreleased as of writing) v10. https://trpc.io/docs/v10/procedures#multiple-input-parsers
const roomProcedure = t.procedure.input(
z.object({
roomId: z.string(),
}),
);
const appRouter = t.router({
sendMessage: roomProcedure
.input(
z.object({
text: z.string(),
}),
)
.mutation(({ input }) => {
// input: { roomId: string; text: string }
}),
});
So, basically I'm trying to receive a call from provider to my app. For that purpose Quickblox gives us a listener to receive the upcoming calls onCallListener. So here is my code snippet that should work but doesn't.
const calleesIds = [4104]
const sessionType = QB.webrtc.CallType.VIDEO
const additionalOptions = {}
let callSession = QB.webrtc.createNewSession(calleesIds, sessionType, null, additionalOptions)
console.log(callSession, "SESSION")
const mediaParams = {
audio: true,
video: true,
options: {
muted: true,
mirror: true,
},
elemId: "myVideoStream"
}
QB.webrtc.onCallListener = function(session: any, extension: object) {
callSession = session
console.log('asdasd')
// if you are going to take a call
session.getUserMedia(mediaParams, function (error: object, stream: object) {
if (error) {
console.error(error)
} else {
session.accept(extension)
session.attachMediaStream("videoStream", stream)
}
})
}
P.S. I also integrated chat which works perfect!
Found the solution by myself! Whenever you create a user and dialog id, search that user in the quickblox dashboard by the dialogId and change its settings: you will see that userId and providerId is the same which is wrong. So put your userId in the userId field and save that. After that you video calling listeners will work fine!)
P. S. also in the backend replace provider token with user token.
With Realm sync of MongoDB, I'm trying to launch a trigger when a realm user is created to insert his newly created ID into my cluster. Here's the javascript function I made that is being called by the trigger :
exports = async function createNewUserDocument({ user }) {
const users = context.services
.get("mongodb-atlas")
.db("BD")
.collection("patients");
const query = { email: context.user.data.email };
const update = {
$set: {
patientId: context.user.id
}
};
// Return the updated document instead of the original document
const options = { returnNewDocument: true };
console.log(context.user.data.email);
return users.findOneAndUpdate(query, update, options)
.then(updatedDocument => {
if(updatedDocument) {
console.log(`Successfully updated document: ${updatedDocument}.`)
} else {
console.log("No document matches the provided query.")
}
return updatedDocument
})
.catch(err => console.error(`Failed to find and update document: ${err}`))
};
When running from the embed editor, while specifying the proper user manually, it's working perfectly. However, when launched by the trigger, it looks like the user is the system user and not the created user, because the error I get in the logs is the same I get when I run from the editor by specifying System user, which is Failed to find and update document: FunctionError: cannot compare to undefined. This makes sense because the System user is not a user per se, so the context.user is undefined.
I find it weird since I specify in the function settings that it should be executed with the permissions of the user calling the function. So my question is, is it possible to access the user.context of a user on his creation, and if so, how would I do it ?
I want to user commander.js and inquirer.js to ask questions and collect the answer to create a User instance:
// index.js
const mongoose = require('mongoose');
const User = require('./model/user')
const {addUser,listAllUsers,findUserByEmail,updateUser,deleteUser} = require('./model_methods/user_methods')
const { program } = require('commander');
var inquirer = require('inquirer');
// connect to DB
const db = mongoose.connect('mongodb://localhost:27017/myImportantDates', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const questions = [
{
type: 'input',
name: 'email',
message: 'user email'
},
{
type: 'input',
name: 'name',
message: 'user name'
},
{
type: 'input',
name: 'password',
message: 'user password'
},
];
program
.version('0.0.1')
.description('The important dates app');
program
.command('add')
.alias('a')
.description('Add a user')
.action(
inquirer
.prompt(questions)
.then( answers => {
addUser(answers)
})
.catch(err =>{
console.log(error)
})
)
program.parse(process.argv);
When I run it with node index.js add, the questions array ask one question and quit:
#DESKTOP-5920U38:/mnt/c/Users/myApp$ node index.js add
? user email
#DESKTOP-5920U38:/mnt/c/Users/myApp$
When I delete program.parse(process.argv), however, everything works fine, it can return me the new User instance.
I check the documents: https://github.com/tj/commander.js/
Still have no idea what happened. Does anybody know more about this??
What I found just now is that if I put program.parse(process.argv) in the beginning like this in the first set up of the program instance:
program
.version('0.0.1')
.description('The important dates app')
.parse(process.argv);
It works too. But I still don't know why the order matters.
In Node.js, process.argv is an array containing the command line arguments passed when the Node.js process was launched. So, program.parse(process.argv) parses the the command line options for arguments, which is bypassing your inquierer.js prompt. You can leave it out.
program.parse(process.argv) is called after setting up your program. It takes the command line arguments (process.argv) and parses them using your declared program, displaying errors or calling action handlers etc.
Based on your example code, an issue is the action handler takes a function parameter. e.g.
.action(() => {
// code goes here
});
I have implemented a page where students can enter in a their Coursework Name with its intended milestones. However, I want to add validation that will only allow users to enter using the following method, two strings with a ':' between them. For example - 'Coursework : Milestone'. Any length of string accepted, as long as it ensures there are two strings with a ':' to separate them in the middle as seen in the example. I am very new to Node.js, Express, jQuery and Handlebars and I have searched for ways to do this but none seemed useful. Below is the only code needed.
in the controller file, a section for creating a new input data
const Task = require('../models/task');
create: function(req, res) {
Task
.create(req.body)
.then(result => {
// result.sort(sortTask)
res.json(result)
})
.catch(err => res.json(err));
}
the model file, task.js, for reference
//dependency
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//data inputted into the database, coursework/milestones section, validation included
const taskSchema = new Schema({
task: {
type: String,
},
completed: {
type: Boolean,
default: false
},
addedAt: {
type: Date,
default: Date.now()
},
});
const Task = module.exports = mongoose.model('Task', taskSchema);
jQuery code to allow these actions to work, in the public folder, eventListeners.js file
$(document).ready(function() {
//index page events
//click even for creating a milestone/coursework
$('#create').on('click', function(e) {
createTask(e);
});
//keypress event that allows milestone?coursework to be created on 'Enter'
$('#task').keypress(function(e) {
if (e.key === 'Enter') {
createTask(e);
}
});
the index.hbs file input section
<input type="text" class="form-control" placeholder="Coursework : Milestone" id="task" autofocus>
RegExp.prototype.test() is what you're looking for. In your use case:
/:/.test(<user input>)