INSERT into the table and return id of the record Supabase JS - supabase

Based on the docs, inserting a new record
const { error } = await supabase
.from('countries')
.insert({ name: 'Denmark' })
returns
{
"status": 201,
"statusText": "Created"
}
For columns that are Is Identity, it automatically assigns a sequential unique number to the column.
How to get the ID of the newly inserted record on Supabase with JavaScript client?

You can add .select() after your insert statement in order to get the newly inserted record.
const { data, error } = await supabase
.from('countries')
.insert({ name: 'Denmark' })
.select()
You will see the inserted record inside data variable. Note that retrieving the inserted record requires you to have not only insert permission, but select permission on RLS policies.
On a side note, you can click on the buttons on the right of the docs to view different use cases. You can see this example on Create a record and return it example.

Related

How To Update Entire Row In Supabase Table? (Getting 400 Error)

I am trying to make an input form where the user can change several values in one row simultaneously which get submitted to the database using the update() method. The values are being read from the Supabase Table into several input fields as defaultValues, which the user can edit and later submit form to update values in the Supabase instance of the table.
Input Form Looks Like This
The input values received from user are stored in a object that has the shape :
inputFields = {
"name": "Piramal Glassed", // NEW
"email": "piramal#glass.com", // NEW
"contact": "98203" // NEW
"pin": 400066,
"city": "Mumbai",
"state": "Maharashtra",
"country": "India",
}
The values marked as // NEW are the ones that have been changed by the user and need to be updated in the subsequent row in the Supabase Table.
I keep getting 400 Error. RLS is disabled for now. This is the function I am using to send the data back to the supabase table.
const { data, error } = await supabase
.from("company")
.update([inputFields.values])
.match([originalFields.values]); // Contains Original Values Of Row That Need To Be Replaced (same shape as inputFields.values)
};
What am I doing wrong here?
It looks like your match filter doesn't work.
I would suggest trying to match row by its ID since you want to update only one row. This way you are actually trying to update all rows that match this data, and that might be causing an issue. I am not sure if we can batch update like this with supabase at the moment.
This is something I'm using in my apps whenever I want to update data for a single row, and I don't have any issues with it. I would suggest to try this, if the question is still relevant. 😊
await supabase.from("company").update(inputFields).match({ id: company.id });
or
await supabase.from("company").update(inputFields).eq("id", company.id)
You could also pass only new values to .update() so you don't update whole row, but only data that has been changed.

How do I delete only the selected data?

When I select a user and an item that a user is using and press the button, I want only that item to disappear. However, the code I created now removes all items the User has.
When adding selected data, I inserted and saved using .add and .save. But I don't know how to delete and save it.
-- spring boot (controller)
#PutMapping(value = {"/users/{id}", "/profileModi/{id}", "/users/productSetting/{id}"})
public ResponseEntity<User> updateUser(#PathVariable("id") long id, #RequestBody User user) {
Optional<User> userData = userRepository.findById(id);
if (userData.isPresent()) {
User _user = userData.get();
_user.setProductInfo(user.getProductInfo());
_user.setRoles(user.getRoles());
_user.setUsername(user.getUsername());
_user.setEmail(user.getEmail());
_user.setPassword(user.getPassword());
_user.setDelYn(user.isDelYn());
return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
-- vue.js
<b-button variant="danger" class="btn btn-fw"
#click="updateProductUser()"
>
cancle
</b-button>
--vue.js (script)
updateProductUser() {
var data = {
id:this.currentUser.id,
email:this.currentUser.email,
delYn:this.currentUser.delYn,
password:this.currentUser.password,
username:this.currentUser.username,
roles:this.currentUser.roles
};
ProductSettingUserDataService.update(this.currentUser.id, data)
.then(response => {
this.currentUser = response.data;
console.log(this.currentUser);
})
.catch(e => {
console.log(e);
});
},
Originally, there was a productInfo table in the User table, and I used a simple method of deleting data by not writing this table. But now I only want to delete one of the data of the productInfo I have selected.
Can you tell which code should be inserted in the controller to be deleted and saved?
I also tried with #DeleteMapping. But it failed...
Relationship table between user and product
As you can see in the picture, User and productInfo have a 1:n relationship. For example, I want to delete only product_id = 12 out of 3 products with user_id = 1.
++ users Table
users
++ productInfo Table
productInfo
The productInfo table exists in the users table.
++ console window
console
Your controller is replacing all the data from the user and your vue.jsscript is not sending product data:
// Data sent by the front
var data = {
id:this.currentUser.id,
email:this.currentUser.email,
delYn:this.currentUser.delYn,
password:this.currentUser.password,
username:this.currentUser.username,
roles:this.currentUser.roles
};
// Controller PUT
User _user = userData.get();
// The front is not sending any productInfo
_user.setProductInfo(user.getProductInfo());
_user.setRoles(user.getRoles());
_user.setUsername(user.getUsername());
_user.setEmail(user.getEmail());
_user.setPassword(user.getPassword());
_user.setDelYn(user.isDelYn());
return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
Since you are not sending product info, the previous product info is deleted. Your front need to send the product info data that you want to preserve.
let me see user table's data. i guess that your userInfo and your productInfo share one table; If you have a productinfo table, you shoud transfer a productId from vue page instead of userId

How to force a filter on server side to a graphql query?

Imagine the condition that I have a query called "users" that returns all the users and these users can be associated with one or more companies, so I have a type UserCompanies (I need it because it saves some more information beyond the relation). I'm using Prisma and I need to force a filter that returns only users that are of the same company as the requester.
I get the information of the company from JWT and need to inject this to the query before sending it to Prisma.
So, query should be like that:
query allUsers {
users {
name
id
status
email
userCompanies{
id
role
}
}
}
and on server side, I should transform it to: (user where is ok, just changing args)
query allUsers {
users(where: {
userCompanies_some: {
companyId: "companyId-from-jwt"
}
}) {
name
id
status
email
userCompanies(where: {
companyId: "companyId-from-jwt"
}){
id
role
}
}
}
I'm seeing a few resolutions to this, but I don't know if it is the best way:
1 - Using addFragmentToInfo, does the job to put conditions on the query, but if the query has a usercompanies already set, it gives me a conflict. Otherwise, it works fine.
2 - I can use an alias for the query, but after DB result I will need to edit all the results in array to overwrite the result.
3 - don't use info on Prisma and filter in js.
4 - Edit info(4th parameter) of type GraphqlResolveInfo

GraphQL - Cannot update a table row

Say I have a table Person with attributes id and name. The GraphQL server is all setup by Postgraphile and working as I can query and create new entry. However, I could not update it. Scratching my head over and over again and I am still unable to find out the cause for this.
This is the mutation I tried that failed me every now and then.
mutation($id: Int!, $patch: PersonPatch!) {
updatePersonById(input: { id: $id, patch: $patch }) {
clientMutationId
}
}
The variables
{
id: 1,
patch: {"name": "newname"}
}
I was using Altair GraphQL client to submit the mutation request and the error message returned was "No values were updated in collection 'people' because no values were found."
The person of id = 1 does exist, confirmed by sending a query personById over to get his name. But I just couldn't update his name.
Edit #1
Below is the gql generated by Altair GraphQL Client
updatePersonById(
input: UpdatePersonByIdInput!
): UpdatePersonPayload
input UpdatePersonByIdInput {
clientMutationId: String
patch: PersonPatch!
id: Int!
}
input PersonPatch {
id: Int
name: String
}
Assuming you're using row-level security (RLS) it sounds like the row to be updated does not pass the required security policies for the currently authenticated user.
Here's a small example; you'll want to adjust it to fit your own permissions system
create table person (id serial primary key, name text);
alter table person enable row level security;
grant select, insert(name), update(name), delete on person to graphql;
create policy select_all on person for select using (true);
create policy insert_all on person for insert with check(true);
create policy update_self on person for update using (id = current_person_id());
create policy delete_self on person for delete using (id = current_person_id());
where
create function current_person_id() returns int as $$
select nullif(current_setting('jwt.claims.person_id', true), '')::int;
$$ language sql stable;
If you need more guidance, feel free to drop into the Graphile chat.

WIX.com Primary key to be used as reference

I'm new to the WIX web development platform.
I need to use the Primary Key of Table 1 to be used as a reference of Table 2, but I cannot use the ID of table 1 for this purpose.
I wonder if the best way is to "copy" this ID in the Title field (Primary Key) of this table 1. How I do that? Is this the best method?
Thank you,
Arturo
Arturo:
Have you tried doing this without using wix code?
Check out this post to see if it is possible.
Now in code the only way to add a reference field from another data collection is to use the ID. But note that ID is the field name used in the data collection for dashboard and Editor view. When accessing the ID value in code you need to use the field key which is _id.
So in your Table2 you need a column (field) that is of type reference and give it a field name like "Table1 Reference". The editor will generate a field key for you that will look like table1Reference.
Now if you have a record from Table1 that you want to link to Table2 you do something like this:
wixData.query('Table1')
.eq('title', 'uniqueTitle')
.find()
.then((results) => {
if (results.totalCount !== 1) {
throw Error('We didn't get a record from Table1');
}
// Success add this in a new record in Table2
let table1Item = results.items[0];
let table2Data = {
table1Reference:table1Item._id,
anotherTable2Field:"Some info for table2"
};
return wixData.save('Table2', table2Data)
.then((savedRecord) => {
// Successful save!
// Do something here....
});
})
.catch((error) => {
console.log(error);
});
Good luck!
Steve

Resources