I'm currently creating an amazon alexa skill that lets users create lists and recall them later with help from AWS's DynamoDB. When my skill attempts to put items into the database table, things turn up green and no errors happen. However, when checking the database table, nothing is written there. Here is the code from my skill where I try to take a slot value and put it into the database:
// query DynamoDB to see if the item exists first
docClient.get(checkIfItemExistsParams).promise().then(data => {
console.log('Get item succeeded', data);
const groceryItem = data.Item;
if (groceryItem) {
const errorMsg = `Grocery item ${name} already exists!`;
this.emit(':tell', errorMsg);
throw new Error(errorMsg);
}
else {
// no match, add the recipe
return docClient.put(dynamoParams);
}
})
.then(data => {
console.log('Add item succeeded', data);
this.emit(':tell', `Grocery item ${name} added!`);
})
.catch(err => {
console.error(err);
});
And here are the server logs first for my skill preparing the request, then for the request actually being sent. No errors occur before or after:
2018-05-21T02:19:53.937Z 72ba8ffb-5c9d-11e8-83b7-af0480d5c4a1 Attempting to add item to list { TableName: 'Groceries',
Item:
{ Name: 'apples',
UserId: 'userid was here, not sure if I should show that publically' } }
host: 'dynamodb.us-east-1.amazonaws.com',
port: 443,
hostname: 'dynamodb.us-east-1.amazonaws.com',
pathname: '/',
path: '/',
href: 'https://dynamodb.us-east-1.amazonaws.com/' },
_clientId: 1 },
operation: 'putItem',
params:
{ TableName: 'Groceries',
Item:
{ Name: 'apples',
UserId: 'userid was here, not sure if I should show that publically' } },
Anyone have any ideas on what might be happening? Thanks.
Related
I am using mongoose to connect my backend (Express) server to database. I want to do normal CRUD operations - but I am able to do it only for direct data in object, but I need to be able to access also array data.
Example of my model:
const LeewaySchema = new mongoose.Schema({
name: {
type: String,
},
shirt: [
{
name: String,
image: String,
},
],
With the following code I am able to update only name of the object, but I need to be able to update also name in shirt array
Here is working approach when changing name of object:
app.put('/update', async (req, res) => {
const updateName = req.body.updateName;
const id = req.body.id;
console.log(updateName, id);
try {
await ClosetModel.findById(id, (error, closetToUpdate) => {
closetToUpdate.name = updateName;
closetToUpdate.save();
});
} catch (err) {
console.log(err);
}
res.send('success');
});
And I tried the same with shirt array, just specifying the correct path
app.put('/update-shirt', async (req, res) => {
const updateShirtName = req.body.updateShirtName;
const id = req.body.id;
try {
await ClosetModel.findById(id, (error, closetToUpdate) => {
closetToUpdate.shirt.name = updateShirtName; // different path here
closetToUpdate.save();
});
} catch (err) {
console.log(err);
}
res.send('success');
});
The server crashes and /update-shirt conflicts with /update path
I am using the same route and frontend for READ
useEffect(() => {
axios
.get('http://localhost:8000/read')
.then((response) => {
setListOfClosets(response.data);
})
.catch(() => {
console.log('error');
});
}, []);
And update name function calling with button onClick:
const updateCloset = (id) => {
const updateName = prompt('Enter new data');
axios
.put('http://localhost:8000/update', {
updateName: updateName,
id: id,
})
.then(() => {
setListOfClosets(
listOfClosets.map((val) => {
return val._id === id
? {
_id: id,
name: updateName,
email: val.email,
}
: val;
})
);
});
};
I don't really know how to do update for shirt's name, I tried to copy paste and just change path and url of course, but it did not work.
The question doesn't actually describe what specific transformation (update) you are attempting to apply to the document. Without knowing what you are attempting to do, there is no way for us to help advise on how to do it.
Say, for example, that the document of interest looks like this:
{
_id: 1,
shirt: [
{ name: "first shirt", image: "path to first shirt" },
{ name: "second shirt", image: "path to second shirt" },
{ name: "third shirt", image: "path to third shirt" }
]
}
Also let's say that the application hits the /update-shirt endpoint with an id of 1 and a updateShirtName of "updated shirt name". Which entry in the array is that string supposed to be applied to? Similarly, how would that information be passed to the server for it to construct the appropriate update.
It is absolutely possible to update documents in an array, here is some documentation about that specifically. But the actual structure of the command depends on the logic that you are attempting to provide from the application itself.
The only other thing that comes to mind here is that the motivation for the schema described in the question seems a little unclear. Why is the shirt field defined as an array here? Perhaps it should instead just be an embedded document. If so then the mechanics of updating the field in the subdocument are more straightforward and none of the aforementioned concerns about updating arrays remain relevant.
just make an update api where you just have to pass the id and and pass the shirt in the findByIdAndUpdate query and hit the postman by passing the below code.
shirt: [
{
name: "jhrh",
image: String,
},
],
I'm building an API to add movies to wishlist. I have an endpoint to get all movies in wishlist. My approach was to get the movie ids (not from mongodb) and make an API request to another API to get the movie objects.
This has been successful so far but the problem now is I am getting two objects fused into one object like below:
{
id: 7,
url: 'https://www.tvmaze.com/shows/7/homeland',
name: 'Homeland',
language: 'English',
genres: [ 'Drama', 'Thriller', 'Espionage' ],
status: 'Ended',
runtime: 60,
averageRuntime: 60,
premiered: '2011-10-02',
officialSite: 'http://www.sho.com/sho/homeland/home',
schedule: { time: '21:00', days: [ 'Sunday' ] },
rating: { average: 8.2 },
image: {
medium: 'https://static.tvmaze.com/uploads/images/medium_portrait/230/575652.jpg',
original: 'https://static.tvmaze.com/uploads/images/original_untouched/230/575652.jpg'
},
summary: '<p>The winner of 6 Emmy Awards including Outstanding Drama Series, <b>Homeland</b> is an edge-of-your-seat sensation. Marine Sergeant Nicholas Brody is both a decorated hero and a serious threat. CIA officer Carrie Mathison is tops in her field despite being bipolar. The delicate dance these two complex characters perform, built on lies, suspicion, and desire, is at the heart of this gripping, emotional thriller in which nothing short of the fate of our nation is at stake.</p>',
}
This is the second object below. Notice how there's no comma separating both objects
{
id: 1,
url: 'https://www.tvmaze.com/shows/1/under-the-dome',
name: 'Under the Dome',
language: 'English',
genres: [ 'Drama', 'Science-Fiction', 'Thriller' ],
status: 'Ended',
runtime: 60,
averageRuntime: 60,
premiered: '2013-06-24',
schedule: { time: '22:00', days: [ 'Thursday' ] },
rating: { average: 6.6 },
image: {
medium: 'https://static.tvmaze.com/uploads/images/medium_portrait/81/202627.jpg',
original: 'https://static.tvmaze.com/uploads/images/original_untouched/81/202627.jpg'
},
summary: "<p><b>Under the Dome</b> is the story of a small town that is suddenly and inexplicably sealed off from the rest of the world by an enormous transparent dome. The town's inhabitants must deal with surviving the post-apocalyptic conditions while searching for answers about the dome, where it came from and if and when it will go away.</p>",
}
My question now is how do I convert both objects to an array and send as a response from my own API. API code is below:
module.exports = {
fetchAll: async (req, res, next) => {
var idsArr = [];
var showsArr;
var shows;
try {
let wishlist = await Wishlist.find({});
if (wishlist == null) {
res.status(404)
.json({
success: false,
msg: 'No Movies Found in Wishlist',
wishlist: []
})
}
// console.log(wishlist);
wishlist.map((item) => {
idsArr.push(item.id);
})
console.log(idsArr);
idsArr.map(async (id) => {
shows = await axios.get(`https://api.tvmaze.com/shows/${id}`);
console.log(shows.data);
// console.log(showsArr);
// showsArr = [shows.data];
})
console.log(showsArr);
return res.status(200)
.json({
success: true,
msg: 'All Movies in Wishlist Fetched',
wishlist: showsArr
})
} catch (err) {
console.log(err);
next(err);
}
},
... // other methods
}
I have tried creating an empty array. shows.data which is the actual response and then I've tried adding it to my array using showsArr.push(shows.data) previously without much success. I get undefined when I log to console.
Here the ids range from 1 to 240+, in case one wants to try out the endpoint - https://api.tvmaze.com/shows/${id}
How would I go about achieving this? Thanks.
Just like when converting the wishlist array to an array of ids, you would need to push the data items into your new showsArr.
However, this doesn't actually work, since it's asynchronous - you also need to wait for them, using Promise.all on an array of promises. And you actually shouldn't be using push at all with map, a map call already creates an array containing the callback return values for you. So you can simplify the code to
module.exports = {
async fetchAll(req, res, next) {
try {
const wishlist = await Wishlist.find({});
if (wishlist == null) {
res.status(404)
.json({
success: false,
msg: 'No Movies Found in Wishlist',
wishlist: []
})
}
const idsArr = wishlist.map((item) => {
// ^^^^^^^^^^^^^^
return item.id;
// ^^^^^^
});
console.log(idsArr);
const promisesArr = idsArr.map(async (id) => {
const show = await axios.get(`https://api.tvmaze.com/shows/${id}`);
console.log(shows.data);
return shows.data;
// ^^^^^^^^^^^^^^^^^^
});
const showsArr = await Promise.all(promisesArr);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
console.log(showsArr);
return res.status(200)
.json({
success: true,
msg: 'All Movies in Wishlist Fetched',
wishlist: showsArr
})
} catch (err) {
console.log(err);
next(err);
}
}
};
I am new to GraphQL.
Started developing an GraphQL app to pull the data from oracle database.
It is very simple application. The query responds with the resultset and can be seen results in console.log; however, it doesn't come to the graphql window (response/resolver window). It throws the error
Cannot return null for non User.email
I tried the promise in the oracle connection. Not sure, why it is not showing the data in GraphQL.
UserType.js
module.exports = new GraphQLObjectType({
name: 'User',
fields: () => {
return{
id: { type: GraphQLID },
email: { type: new GraphQLNonNull(GraphQLString) }
}
}
});
DBConnection.js
module.exports = oraPool => {
return {
getUsers(apiKey){
return oracledb.createPool(oraConfig).then(function() {
console.log("Connection Pool created");
return oracledb.getConnection().then(function(conn) {
return conn.execute(
//`SELECT 'User ' || JSON_OBJECT ('id' VALUE id, 'email' VALUE email) FROM users where id = :id`
`SELECT * FROM users WHERE id = :id`
,[apiKey]).then(result => {
//console.log(result.metaData);
console.log(humps.camelizeKeys(result.rows[0]));
conn.close();
return humps.camelizeKeys(result.rows[0]);
})
.catch(function(err) {
console.log(err.message);
return connection.close();
});
})
.catch(function(err) {
console.error(err.message);
});
})
}
}
}
Type.js
const RootQueryType = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: {
key: { type: new GraphQLNonNull(GraphQLString) }
},
resolve: (obj, args, { oraPool }) => {
return oradb(oraPool).getUsers(args.key);
}
}
}
});
This code is pretty tangled, I recommend starting from scratch. For example, you're calling createPool each time a query is run. You should create the pool during the initialization of your app instead.
Although you said this will be a simple app, it could always grow. Creating a from scratch GraphQL server isn't trivial. I recommend bringing in some help via join-monster. Unfortunately, join-monster is no longer being actively developed. But it's pretty stable and it's a lot better than starting from scratch. Here's a nice overview of how it works:
https://github.com/stems/join-monster/tree/master/src
I recently did a talk on GraphQL which you can see here: https://www.slideshare.net/DanielMcGhan/intro-to-graphql-for-database-developers
For the demo, I took a simple API pattern I describe in this blog series and adapted it to be a GraphQL server on the common EMP and DEPT demo tables. You can access the code here:
https://www.dropbox.com/s/cnvyrlik7irtbwm/graphql-api.zip?dl=0
Also, another one of my colleagues talks about GraphQL here:
https://blogs.oracle.com/opal/demo:-graphql-with-node-oracledb
My Database is arangodb. What i want to do is : I have data like this:
_id:authModel/1209597
_key:1209597
{
email: 'abc#gmail.com',
password: 'password',
subuser_ids:[ '811289', '1209611' ],
id: '1209597'
}
_id:authModel/811289
_key:811289
{
email: 'pqr#gmail.com',
password: 'password',
id: '811289'
}
actually i need to fetch data which is the ids in subuser_ids array, ie the subuser_ids contain 2 ids. I need to fetch the data that the subuser_id hold. suppose subuser_id is "811289" that is _id="811289" i need to fetch that data. am using arangodb and loopback. also i write an remote method to accesss that data. What i have is :
model.js
var server = require("../../server/server");
module.exports = function (Authmodel) {
Authmodel.on("attached", function () {
Authmodel.getApp(function (err, app) {
Authmodel.getSubUsers = function (params, cb) {
var result = [];
params.forEach(function (id) {
app.models.authModel.findOne({ "_id": id }, function (err, r) {
console.log("err", err);
console.log("r", r);
result.push(r);
});
})
cb(null, result);
};
});
});
Authmodel.remoteMethod('getSubUsers', {
accepts: { arg: 'params', type: 'array' },
returns: { arg: 'result', type: 'array' }
});
};
i got the log in the result console but that data is not correct.
How can i solve this issue? i need to fetch all subuser_ids data. any help will really appreciable and helpfull.
I am a noob with Node.JS.
I am using CouchDB and Cradle.
In couchDB I have a database named 'test' and inside it I have a document named 'exercise'.
The document has 2 fields: "FullName" and "Age".
The code in order to save the data is as follows:
var cradle = require('cradle');
var connection = new(cradle.Connection)('http://127.0.0.1', 5984, {
auth: { username: 'toto_finish', password: 'password' }
});
var db = connection.database('test');
db.save('exercise', {
FullName: param_name, Age: param_age
}, function (err, res) {
if (err) {
// Handle error
response += ' SAVE ERROR: Could not save record!!\n';
} else {
// Handle success
response += ' SUCESSFUL SAVE: The record was saved in CouchDB!\n';
}
http_res.end(response);
});
this code works well and it saves the data to the CouchDB.
My problem is when I want to read the data.
The code that I wrote is:
var cradle = require('cradle');
var connection = new(cradle.Connection)('http://127.0.0.1', 5984, {
auth: { username: 'toto_finish', password: 'password' }
});
var db = connection.database('test');
db.view('exercise/all', {descending: true}, function(err, res)
{
console.log(res);
res.forEach(function (row) {
response = 'FullName: ' + row.FullName + '\n Age: ' + row.Age + '\n';
});
});
http_res.end(response);
when I am trying to print response, response is empty and I don't know what I am doing wrong. I know that it does not go inside the forEach loop but I don't understand why.
the console output is:
[ { id: 'exercise',
key: null,
value:
{ _id: 'exercise',
_rev: '1-7042e6f49a3156d2099e8ccb3cc7d937',
FullName: 'Toto Finish',
Age: '30' } } ]
Thanks in advance for any response or answer.
Try moving the http_res.send() call inside the callback provided to db.view - the anonymous function( err, res ) { }.
I'm not sure however about the .forEach statement, you'll only get the last value from your query in the response variable, you should look into that as well.
spotirca is right
The db.view function is async so http_res.end(response) gets called before the view returns any data.
You can prove this by returning the date in both the console.log and http_res.end
console.log(res, new Date())
and
http_res.end(response, new Date());
The http response will have the earlier date/Time.