Displaying data from Appwrite into sveltekit - sveltekit

So, I have an appwrite and sveltekit application running. This is my first time using both. I have managed to set up appwrite sdk and connected to database and have api data stream coming in when I log it.
Here is the data I get from appwrite in the console.
Now I want to display this data and I am not sure where I am missing it. The info I find is for consuming REST api data and not really for data coming in from appwrite. Here is my code on the svelte side:
<script>
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
let appdata = promise;
</script>
{#each appdata.documents as front}<p>{front.content}</p>{/each}
<div class="hero min-h-screen" style="background-image: url(../src/images/header_front.png);">
<div class="hero-overlay bg-opacity-60"></div>
<div class="hero-content text-center text-neutral-content">
<div class="max-w-md">
<h1 class="mb-5 text-5xl font-bold prose">Welcome to Nafuna!</h1>
<p class="mb-5 prose">
I know I am missing someting in how svelte displays this but please assist!
I tried to convert the data from the original const into let because had read that svelte displays from let but that didnt work either.
EDIT: I have included a return as suggested here and I still cant get the data to display so I thought I would paste the code here again with the updates:
<script lang="ts">
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
promise.then(function (response) {
console.log(response); // Success
return response;
}, function (error) {
console.log(error); // Failure
throw error;
});
// let appdata;
// appdata = response;
</script>
{#each appdata as front}<p>{front.documents.content}</p>{/each}

Your
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
may be causing a problem because it changes the promise to resolve to nothing. You could try to make sure it returns the actual data:
promise.then(function (response) {
console.log(response); // Success
return response;
}, function (error) {
console.log(error); // Failure
throw error;
});

Here's a way without #await in case the whole appdata object is needed
reactive variable - ternary operator - ?. - ??
<script lang="ts">
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
let appdata;
$: documents = appdata ? appdata.documents : [] //or appdata?.documents ?? []
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
promise.then(function (response) {
console.log(response); // Success
appdata = response
}, function (error) {
console.log(error); // Failure
throw error;
});
</script>
{#each documents as front}
<p>
{front.content}
</p>
{/each}
In case it's fine to only use the documents
<script lang="ts">
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
let documents = [];
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
promise.then(function (response) {
console.log(response); // Success
documents = response.documents
}, function (error) {
console.log(error); // Failure
throw error;
});
</script>
{#each documents as front}
<p>
{front.content}
</p>
{/each}
Using #await to benefit from showing a message while loading and in error case (here appdata will be only available inside the :then block)
<script lang="ts">
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
</script>
{#await promise}
<p>...waiting</p>
{:then appdata}
{#each appdata.documents as front}
<p>
{front.content}
</p>
{/each}
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
Using #await with documents in component scope in case needed. Using an underscore in {:then _} as variable name indicates that the value doesn't matter and lets documents inside the #each loop point to the variable in the script tag
<script lang="ts">
import { Client, Databases } from "appwrite";
const client = new Client();
const databases = new Databases(client);
let documents = []
client
.setEndpoint('http://localhost/v1') // Your API Endpoint
.setProject('63d89956ac3d018e22ff') // Your project ID
;
const promise = databases.listDocuments('63d89aba02f41e8c4003', '63d89ad33cb270e9c8c1');
promise.then(function (response) {
console.log(response); // Success
documents = response.documents
}, function (error) {
console.log(error); // Failure
throw error;
});
</script>
{#await promise}
<p>...waiting</p>
{:then _}
{#each documents as front}
<p>
{front.content}
</p>
{/each}
{:catch error}
<p style="color: red">{error.message}</p>
{/await}

Related

I can't update my contacts

I read some tutorials on MEAN Stack and I'm currently working on one which is almost complete, until I tried my update function. I keep on receiving a 400 message and when i look at the chrome dev tools and under the network tab I read the response which is "_id" is not allowed.
here is the update function
$scope.update = () => {
console.log($scope.contact._id);
$http.put('/api/contacts/updatecontact/' + $scope.contact._id, $scope.contact)
.then(function(data) {
alert('Data was updated Successfully');
refresh();
});
};
here is the api.
app.put('/api/contacts/updatecontact/:id', (req, res) => {
const id = req.params.id;
console.log(req.body.name);
// validation
const { error } = validateInput(req.body);
if (error){
return res.status(400).send(error.details[0].message);
}
const updatedContact = Contact.where({ _id: id });
updatedContact.update({
$set: { name: req.body.name, email: req.body.email
}
}, (err, contact) => {
if(err){
console.log('error occured');
}
res.json(contact);
console.log('contact successfully updated');
});
console.log(updatedContact);
});
hope i can get some help with this.
It seems the node.api is validating the json object that you are passing. Make sure the properties you sent form the client.
Make sure you are not validating or remove the validation on the node.

Angularjs Post request to server

How would i gather that info im sending from the client? in this case, the id?
How can I get the id?
I do use client sided request:
return $http.post('/api/kill', {id:4}, {
headers: {}
})
and when i check server sided for req.body console.log(Req.body) i do get:
{ '{"id":4}': '' }
req.body.id returns:
undefined
How can i get the id of 4?
EDIT1:
the main code is located at https://github.com/meanjs/mean
server sided code:
app.post('/api/kill', function (req, res) {
console.log(req.body); // { '{"id":4}': '' }
console.log(req.body.id); // undefined
});
You need to assign that id property to an object like
item = { id : 4 }
Lets suppose you have a text-box and the user wants to save a new item by inserting its name in it and click on submit.
Lets also suppose you are using a MongoDB collection of items, which have only id field for simplicity.
Here's what you should do to get it going easy.
Make sure you are importing bodyParser
var bodyParser = require('body-parser');
HTML - saving a new item with custom id
<div class="form-group">
<label for="id">ID</label>
<input type="text" class="form-control" id="id" ng-model="ItemController.formData.id">
</div>
<button type="submit" ng-click="ItemController.createItem()" >Submit</button>
Angular part - ItemController.js
'use strict';
angular
.module('myApp')
.controller('ItemController', ItemController);
function ItemController($http) {
var vm = this;
/** Creates a New Marker on submit **/
vm.createItem = function() {
// Grabs all of the text box fields
var itemData = {
id : vm.formData.id
};
// Saves item data to the db
$http.post('/api/kill', itemData)
.success(function(response) {
if(response.err){
console.log('Error: ' + response.err);
} else {
console.log('Saved '+response);
}
});
};
}
Route Handling - routes.js
var ItemFactory = require('./factories/item.factory.js');
// Opens App Routes
module.exports = function(app) {
/** Posting a new Item **/
app.post('/api/kill', function(req, res) {
ItemFactory.postItem(req).then( function (item) {
return res.json(item);
});
});
};
Post into MongoDB - item.factory.js
var Item = require('../models/item-model');
exports.postItem = postItem;
function postItem(item) {
return new Promise( function (resolve, reject) {
var newItem = new Item(item.body);
newItem.save(function(err) {
if (err){
return reject({err : 'Error while saving item'});
}
// If no errors are found, it responds with a JSON of the new item
return resolve(item.body);
});
});
}
If you try console.log() on the different pieces of code where I passed the item, you can properly see an object with id property.
I hope I've been helpful.
you miss the single quote :
var obj = { 'id':4 };
console.log(obj.id); //display 4
in your example :
return $http.post('/api/kill', {'id':4}, {
headers: {}
})
response you are getting is not in object form
{ '{"id":4}': '' }
it is a key value pair and key is a string
'{"id":4}'
In order to get the right value at your end your json response shoulb be like
{ { 'id':4 } }
and then it will work like
console.log(req.body); // { {"id":4} }
console.log(req.body.id); // 4
Make sure that you enabled JSON body parser in your node.js application.
var bodyParser = require('body-parser');
....
app.use(bodyParser.json());

How to delete Amazon s3 file w/ nodejs / angular

var awsSdk = require('aws-sdk');
awsSdk.config = {
"accessKeyId": "key",
"secretAccessKey": "secret",
"region": "us-east-1"
}
var s3 = new awsSdk.S3({
accessKeyId: 'key',
secretAcessKey: 'secret'
});
exports.awsDelete = function(req, res){
s3.deleteObject({
Bucket: 'bucket',
Key: req.body.photo
}, function(err,data){
if (err) console.log('delete err', err);
console.log(data);
});
};
I can't figure out how to make this work (yet).
initially, I was getting a "no config" error, so I added the awsSdk.config json above. Now, it's just getting hung / pausing with no error. I am getting the expected key in req.body.photo.
My hunch is that i'm missing something in my config..
What am I missing / screwing up?
Update
I've added the code suggested below, but still no luck. I'll show how i'm passing my parameter:
updated code from answer below:
'use strict';
var aws = require('./aws');
var amazon = require('aws-sdk');
amazon.config = new amazon.Config();
amazon.config.accessKeyId = aws.key;
amazon.config.secretAccessKey = aws.secret;
amazon.config.region = aws.region;
var s3 = new amazon.S3();
exports.awsDelete = function(req, res){
var params = {
Bucket: aws.bucket,
Key: res.body.photo
};
s3.deleteObject(params, function(err, data) {
if (err) console.log(err)
else console.log("Successfully deleted myBucket/myKey");
});
};
route:
app.post('/awsDelete', uploads.awsDelete);
Front end Angular:
factory:
angular.module('clientApp').factory('Uploads', function($http) {
return {
delete: function(data){
console.log('delete fired');
return $http.post('/awsDelete', data);
}
};
});
angular controller:
angular.module('clientApp').controller('Distiller-editCtrl', function(Uploads){
$scope.item = {}
$scope.delete = function(){
Uploads.delete($scope.item).then(function(res){
console.log(res)
});
};
});
Seems it 'sort of works'. But something is making it take an extremely long time:
POST /awsDelete 200 120007ms
If I refresh the page, that causes it to successfully delete it as well.
Does anyone notice anything in my code that could be causing such a long response time.
Also, not getting the "successfully completed" console.log
I just tested this in node and it worked fine, obviously you need to put in your own accesskey, secretaccesskey, bucket and bucket key:
var AWS = require('aws-sdk');
AWS.config = new AWS.Config();
AWS.config.accessKeyId = "";
AWS.config.secretAccessKey = "";
AWS.config.region = "us-east-1";
var s3 = new AWS.S3();
var params = {
Bucket: 'test537658ghdfshgfd',
Key: '1.png'
};
s3.deleteObject(params, function(err, data) {
if (err) console.log(err)
else console.log("Successfully deleted myBucket/myKey");
});
Alternatively you can use Minio-Js client library, its Open Source and compatible with AWS S3.
Below is remove-object.js example, you can find complete list here
var Minio = require('minio')
var s3Client = new Minio({
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY'
})
// Remove an object name my-objectname.
s3Client.removeObject('my-bucketname', 'my-objectname', function(e) {
if (e) {
return console.log(e)
}
console.log("Success")
})
Please replace YOUR-ACCESSKEYID and YOUR-SECRETACCESSKEY with your own also replace the endPoint to the one you have your bucket is created.
us-east-1: 's3.amazonaws.com',
us-west-1 : 's3-us-west-1.amazonaws.com',
us-west-2 : 's3-us-west-2.amazonaws.com',
eu-west-1: 's3-eu-west-1.amazonaws.com',
sa-east-1: 's3-sa-east-1.amazonaws.com',
eu-central-1: 's3-eu-central-1.amazonaws.com',
ap-southeast-1: 's3-ap-southeast-1.amazonaws.com',
ap-southeast-2: 's3-ap-southeast-2.amazonaws.com',
ap-northeast-1: 's3-ap-northeast-1.amazonaws.com'
Installing Monio-js
$ npm install --save minio
Hope it helps.
Disclaimer: I work for Minio.

Angular API call fails in MEAN application

In a MEAN app I am trying to allow an authorised user (email and password login) to change their username.
I can successfully use Postman to PUT a new username to http://localhost:3000/api/users/xxxxxxxxxxxxxxxx.
But the angular code fails.
Here is the relevant part of the edit page:
<form ng-submit="user.saveUser()">
<div class="form-group">
<label> New Username</label>
<input type="text" class="form-control" ng-model="user.userData.name">
</div>
Here is the controller:
.controller('userEditController', function($routeParams, User) {
var vm = this;
vm.type = 'edit';
User.get($routeParams.user_id)
.success(function(data) {
vm.userData = data;
});
// function to save the user
vm.saveUser = function() {
vm.processing = true;
vm.message = '';
// call the userService function to update
User.update($routeParams.user_id, vm.userData)
.success(function(data) {
vm.processing = false;
// clear the form
vm.userData = {};
// bind the message from our API to vm.message
vm.message = data.message;
});
};
});
Here is the service:
// update a user
userFactory.update = function(id, userData) {
return $http.put('/api/users/' + id, userData);
};
at this point userData contains name: “Fred” or whatever was input to the form
and here is the api.js
apiRouter.route('/users/:user_id')
// get the user with that id
.get(function(req, res) {
User.findByIdAndUpdate(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// return that user
res.json(user);
});
})
// update the user with this id
.put(function(req, res) {
console.error(req.params.user_id);
User.findById(req.params.user_id, function(err, user) {
if (err) return res.send(err);
// set the new user information if it exists in the request
if (req.body.name) user.name = req.body.name;
// save the user
user.save(function(err) {
if (err) return res.send(err);
// return a message
res.json({ message: 'User updated!' });
});
});
});
(I had to use findByIdAndUpdate instead of findById because of a CastError.)
Although the console states:
XHR finished loading: PUT http:/localhost/3000/api/users/user_id
The value of req.params.user_id is just user_id.
The terminal shows:
PUT /api/users/user_id 200 4.040 ms - 2273
GET /api/users/user_id - - ms - -
GET /api/users/user_id - - ms - -
GET /api/users/user_id - - ms - -
Like I say Postman can communicate with the API and can update without problems. I am stumped, and hopefully someone will put me out of my misery
I had to change tack with this one. The fact that a manually entered user_id in Postman worked should have told me that the user_id provided by the Angular code was not correct. So I made sure that the JWT included the user_id:
var token = jwt.sign({
name: user.name,
email: user.email,
user_id: user._id
Then added an api endpoint to get user information:
apiRouter.get('/me', function(req, res) {
res.send(req.decoded);
});
Then connected a service:
userFactory.get = function() {
return $http.get('/api/me/');
};
Then in the controller I could call get:
User.get()
.success(function(result) {
$scope.user_id = result.user_id;
});
$scope.user_id now has the correct user_id which I can pass into the update method:
User.update($scope.user_id, vm.userData)
.success(function(data)
So now it works as intended.

Express + Angular update route: Error: Cannot PUT

I'm trying to update a schema using form, however, both on app.put and app.post (which I've seen as a possible solution) i get
PUT https://myapp-demo.herokuapp.com/api/events/5523da4d97c5000300f6e713 404 (Not Found)
and error from ajax callback
Error: Cannot PUT /api/events/5523da4d97c5000300f6e713
on clientside, I make this request:
$scope.saveEvent = function(id) {
$http.put('../api/events/' + id, $scope.formData)
.success(function (data) {
$scope.events = data;
})
.error(function(data) {
console.log('Error: ' + data);
})
};
In express routes, I do this:
app.put('../api/events/:id', function (req, res){
var user = req.user;
var id = req.params.id;
var update = {
$set: {
title: req.body.title,
description: req.body.description,
}
};
Event.findByIdAndUpdate(id, update, function (err, event) {
if(!event) {
res.statusCode = 404;
return res.send({ error: 'Not found' });
}
console.log("event updated");
Event.find(function(err, events) {
if (err){
res.send(err)
};
res.json(events);
});
});
});
I tried to pass event._id differently, by using req.params.id and passing id with form like req.body.id, it all leads to the same result. I've also read about creating hidden input for helping method-override to override form methods. However, having this didn't help.
<input type="hidden" name="_method" value="put">
<md-button class="md-raised md-primary" ng-click="saveEvent(eventId)">Save</md-button>
UPDATE
Indeed, the initial proble was in my put route. I've found a new problem now. When I try to update it again, I get
Error: Object {error: "Not found"}
It happens even after I refresh page or restart server.
The following is invalid:
app.put('../api/events/:id'...
It needs to be in reference to the namespace, or in your case the root:
app.put('/api/events/:id'...

Resources