Why does using fetch data in nuxt3 - fetch

I'm new to Nuxt. I have an error retrieving data. How can I fix it?

If you are using useFetch without specifying the type of the result, typescript cannot know, what type it is.
You could tell typescript that you are receiving a list of users from an endpoint and what a user looks like by doing something like this:
interface User {
id: number
name: string
email: string
}
const {data: users} = useFetch<User[]>('api.example.com');
useFetch returns the (parsed) body of the response in data. Looking at what the URL https://reqres.in/api/users really provides, you would probably want to access the data attribute of the body. You'd need something like this to get to the list of users:
interface User {
id: number
first_name: string
last_name: string
email: string
}
const { data: body } = useFetch<{ data: User[] }>('https://reqres.in/api/users')
const users = body.value?.data ?? []

Related

How can I use the Prisma adapter for Next-Auth without email and emailVerified values

I am using next-auth with a custom provider and the Prisma adapter and I only want to store the values: id, name, country, avatar, and gender. However, I am getting this error:
[next-auth][error][adapter_error_createUser]
https://next-auth.js.org/errors#adapter_error_createuser
Invalid `p.user.create()` invocation in
.\node_modules\#next-auth\prisma-adapter\dist\index.js:6:38
3 exports.PrismaAdapter = void 0;
4 function PrismaAdapter(p) {
5 return {
→ 6 createUser: (data) => p.user.create({
data: {
name: [redacted],
wcaId: [redacted],
country: [redacted],
avatar: [redacted],
gender: [redacted],
email: undefined,
emailVerified: null
~~~~~~~~~~~~~
}
})
Unknown arg `emailVerified` in data.emailVerified for type UserCreateInput. Available args:
...
The profile object in my custom provider looks like this:
profile(profile) {
return {
id: profile.me.id,
name: profile.me.name,
country: profile.me.country_iso2,
avatar: profile.me.avatar.url,
gender: profile.me.gender,
};
},
Everything in my Prisma schema follows the example in https://next-auth.js.org/adapters/prisma#setup except the User model which is like so:
model User {
id String #id #default(cuid())
name String
country String #db.Char(2)
avatar String
gender String #db.Char(1)
accounts Account[]
sessions Session[]
// Temporary workaround:
email String? #unique
emailVerified DateTime? #map("email_verified")
}
In the error, the adapter appears to have added email and emailVerified to the data object so the temporary workaround I am using is adding email and emailVerified columns to my Prisma model as shown above. However, this is not ideal, and I would like to know how I can remove these unnecessary columns from my database as their values are always undefined and null.

How to use custom object types in Hasura actions?

I want to create an action with the following input:
input PurchaseInput {
user: UserInfo!
}
UserInfo is defined as an object:
type UserInfo {
accessToken: String!
userId: Int!
}
However Hasura doens't like this and returns a 400 on saving the action.
Is it possible to define custom input types in Hasura? I feel limited by String, Int, Float, Boolean etc.
You can absolutely create custom types like in your example
type UserInfo {
accessToken: String!
userId: Int!
}
So the error is of some other origin ( action response.... ).
Hasura only has a limitation of nested object types, for example, you can not do type definition like this in action :
type User {
userId: Int!
}
type UserInfo {
accessToken: String!
user: User!
}

Indexable signature not found in object literal in Flow

I have this interface:
interface IFormData {
[string]: string
};
export type { IFormData };
It's simple interface that accepts key-value only string. But when I use this,
const formData:IFormData = { email: '...', password: '...' };
it gives me this error:
[flow] property $key of IFormData (Indexable signature not found in object literal)
I also tried this, but it gives me same error:
var formData: IFormData; // Error
formData['email'] = ...;
formData['password'] = ...;
I searched this on google almost 2 days, but still stuck in here and I need some help!
Any advice will very appreciate it.
If you switch from interface to type, Flow seems to be a lot happier with this sort of thing:
type IFormData = {
[string]: string
}
const formData: IFormData = { email: '...', password: '...' };
I'm guessing the fact that interfaces are nominally typed, rather than structurally typed, has something to do with this.

Meteor - Validating new user document serverside

I'm having trouble with this seemingly trivial stuff, harrrr!
I have this user document:
userData = {
account: {
type: 'free'
},
profile: {
name: 'Artem',
},
username: 'aaa#gmail.com',
password: '123'
};
Which I'm sending client-side: Accounts.createUser(userData);
Then server side I want to check if account type equals 'free'. If it doesn't - I want to abort new user creation (and hopefully throw error client side)
There are 2 functions which I've found in the docs that presumably can help me do it:
Accounts.validateNewUser
Problem: it receives 'trimmed-down' user object which doesn't contain properties other than profile, username, password, email. Thus I cannot validate account.type as it doesn't exist on user object being validated.
Accounts.onCreateUser
Problem: it is called after a generic user object is created and there is no way I can cancel inserting new document in Users collection. It absolutely requires to return a user document. If I return undefined it throws errors on server:
Exception while invoking method 'createUser' Error: insert requires an argument
It also doesn't allow to throw method errors (as it's not a method) -> thus I cannot log error client side.
You can use Accounts.validateNewUser with little change to your data structure:
userData = {
profile: {
name: 'Artem',
account : {
type : 'free'
}
},
username: 'aaa#gmail.com',
password: '123'
};
Then you should be able to access data you need.
As far as I remember there were some discussion on meteor forum about removing profile field, that's why I'm solving this kind of problems in different way. For me Meteor.users is collection which should not be changed for sake of peace in mind - it could be changed by future version of meteor. My approach require to write more code in the beginning, but later it pays off, because you have place to store data about user and Meteor.users collection has docs with minimal amount of data.
I would use jagi:astronomy#0.12.1 to create schema and custom methods. In general I would create new collection UserAccounts with schema:
UserAccount = new Astro.Class( {
name: 'UserAccount',
collection: 'UserAccounts',
fields: {
'userId' : {type: 'string'},
'type' : {type: 'string', default:'free'}
},
} )
and add schema to Meteor.users :
User = new Astro.Class( {
name: 'User',
collection: Meteor.users,
fields: {
'services' : {type: 'object'},
'emails' : {type: 'array'}
},
methods:{
account : function(){
return UserAccounts.findOne({userId:this._id})
}
}
} )
The usage looks like this:
var user = Meteor.users.findOne();
user.account().type
In summary:
Accounts.onCreateUser : always allow to create user account and always create UserAccount which corresponds to it ( with field userId)

Meteor private messaging between users

Right now I have a working messaging system developed in Meteor where users can send private messages to each other.
The server looks like this:
// .. lot of code
Meteor.publish("privateMessages", function () {
return PMs.find({ to: this.userId });
});
PMs.allow({
insert: function(user, obj) {
obj.from = user;
obj.to = Meteor.users.findOne({ username: obj.to })._id;
obj.read = false;
obj.date = new Date();
return true;
}
});
// .. other code
When the user subscribes to privateMessages, he gets a mongo object that looks like this:
{ "to" : "LStjrAzn8rzWp9kbr", "subject" : "test", "message" : "This is a test", "read" : false, "date" : ISODate("2014-07-05T13:37:20.559Z"), "from" : "sXEre4w2y55SH8Rtv", "_id" : "XBmu6DWk4q9srdCC2" }
How can I change the object to return the username instead of the user id?
You need to do so in a way similar to how you changed username to _id. You can create a utility function:
var usernameById = function(_id) {
var user = Meteor.users.findOne(_id);
return user && user.username;
};
Edit:
If you don't want to poll minimongo for each message, just include username instead of _id inside your message object. Since username is unique, they will be enough.
If in your app you allow users to change username, it might be a good idea to also keep the _id for the record.
In one of larger apps I've been working with we kept user's _id in the model (to create links to profile etc.), as well as cached his profile.name (for display purposes).
I suggest adding the collection helpers package from atmosphere. Then create a helper for PMs called toUser that returns the appropriate user.
Then you can get the name using message.user.name.

Resources