List items in MongoDB array - javascript

I'm trying to list a series of paragraphs I have stored as an array in a document field "body". Where I have x items in the array, it outputs the whole field x times. If someone can point me in the right direction I'd so appreciate it. I know the issue is just where I have #{pages.body} at the end, because obviously that returns the whole field, but I'm not sure how to change it.
route:
exports.cont = function(db) {
return function(req, res) {
var collection = db.get('contents');
collection.find({href:req.params.href},{},function(e,docs){
res.render('cont', {
"cont" : docs
});
});
};
};
display page in Jade:
each pages, i in cont
.box
h1 #{pages.title}
.img
img.body(src="#{pages.img}")
.text
each para, i in pages.body
p #{pages.body}

Solution:
each pages, i in cont
.box
h1 #{pages.title}
.img
img.body(src="#{pages.img}")
.text
each paragraph, i in pages.body
p #{paragraph.text}
MongoDB document setup:
{
img: "xxxxxx",
body:
[
{ text: "xxxxxxx" },
{ text: "xxxxxxx" },
{ text: "xxxxxxx" }
]
}
If you want the option of HTML formatting in each paragraph, just replace the # before {paragraph.text} with !

Related

IMDB API request GraphQL Error 'ClientError: Cannot query field "Image" on type "MainSearchEntity"'

I'm trying to get the top 10 movie name recommendations that match the search term 'Africa', based on the IMDB API demo here https://developer.imdb.com/documentation/api-documentation/sample-queries/search/?ref_=side_nav.
I need the query to return the movie id, title, image poster and filming location.
However, when I run the graph query below, I get the error 'ClientError: Cannot query field "Image" on type "MainSearchEntity".|Cannot query field "FilmingLocation" on type "MainSearchEntity"."
The query works fine when I remove the code Image { url } FilmingLocation { text } from the script.
What could be the problem with the query below?
How do I include the poster image and filming location in the query?
Thanks!
{
# Get the top 10 name recommendations that match the search term Africa.
mainSearch(
first: 10
options: {
searchTerm: "Africa"
isExactMatch: false
type: TITLE
includeAdult:false,
}
) {
edges {
node {
entity {
# For returned Names, get me the id, name text, image, year, country
... on Name {
id
nameText {
text
}
}
Image {
url
}
FilmingLocation {
text
}
}
}
}
}
}
Assuming the two fields that are causing you trouble are called posterImage and filmingLocation (usually field names are in camelCase), I guess your query should be:
query {
# Get the top 10 name recommendations that match the search term Africa.
mainSearch(
first: 10
options: {
searchTerm: "Africa"
isExactMatch: false
type: TITLE
includeAdult:false,
}
) {
edges {
node {
entity {
# For returned Names, get me the id, name text, image, year, country
... on Name {
id
nameText {
text
}
image {
url
}
filmingLocation {
text
}
}
}
}
}
}
}
The problem seems to be that the two fields were not inside the MainSearchEntity. Hope it helps!
Fixed it:
Turns out the image poster field is 'primaryImage' not Image.
Here's the working code:
{
# Get the top 10 name recommendations that match the search term Jennifer.
mainSearch(
first: 10
options: {
searchTerm: "Jennifer"
isExactMatch: false
type: TITLE
includeAdult:false,
}
) {
edges {
node {
entity {
# For returned Names, get me the id, name text, image, year, country
... on Title {
id
titleText {
text
}
primaryImage {
url
}
filmingLocations(first:1) {
edges{
node{
text
}
}
}
}
}
}
}
}
}

Redis Search unable to query by text field

I have a redis database where i store has hset entries with
A MAC address called mid in the form XX:XX:XX:XX:XX:XX
A timestamp
A geographical position called position
A text payload called message
I would like to be able to index those objects by the mid, the timestamp and the position (I will never query from information about the message).
This is the code for the schema of the index,
await client.ft.create(
'idx:cits',
{
mid: {
type: SchemaFieldTypes.TEXT
},
timestamp: {
type: SchemaFieldTypes.NUMERIC,
sortable: true
},
position: {
type: SchemaFieldTypes.GEO
}
},
{
ON: 'HASH',
PREFIX: 'CITS'
}
)
And I insert new entries using
await client.hSet('CITS:19123123:0:0:00.00:5e:00:53:af', {
timestamp: 19123123,
position: '0,0',
mid: '00:00:5e:00:53:af',
message: 'payload'
})
I can perfectly query by timestamp and position both in the javascript code using
await client.ft.search('idx:cits', '#timestamp:[100 19123180] #position:[0 0 10 km]')
and in the redis-cli using
FT.SEARCH idx:cits "#timestamp:[100 19123180] #position:[0 0 10 km]"
But it does not work when querying by the mid field.
I have tried both
await client.ft.search('idx:cits', '#mid:"00:00:5e:00:53:af"')
and in redis-cli
FT.SEARCH idx:cits idx:cits '#mid:"00:00:5e:00:53:af"'
I have also tried exchanging the " and the ' as well as eliminating them to see if it worked without any result.
I have also tried storing the mac addresses as XX.XX.XX.XX.XX.XX instead of XX:XX:XX:XX:XX:XX and did not result either.
I have also seen that it will not work for 00:00:5e:00:53:af but instead it works for ff.ff.ff.ff.ff.ff.
I'm not sure why I am not able to query by the mid, I would really appreciate if someone could help me out.
Here is an example script
const { createClient, SchemaFieldTypes } = require('redis')
const client = createClient()
async function start(client) {
await client.connect()
try {
// We only want to sort by these 3 values
await client.ft.create(
'idx:cits',
{
mid: {
type: SchemaFieldTypes.TEXT
},
timestamp: {
type: SchemaFieldTypes.NUMERIC,
sortable: true
},
position: {
type: SchemaFieldTypes.GEO
}
},
{
ON: 'HASH',
PREFIX: 'CITS'
}
)
} catch (e) {
if (e.message === 'Index already exists') {
console.log('Skipping index creation as it already exists.')
} else {
console.error(e)
process.exit(1)
}
}
await client.hSet('CITS:19123123:0:0:00.00.5e.00.53.af', {
timestamp: 19123123,
position: '0,0',
mid: '00.00.5e.00.53.af',
message: 'payload'
})
await client.hSet('CITS:19123123:0.001:0.001:ff.ff.ff.ff.ff.ff', {
timestamp: 19123123,
position: '0.000001,0.000001',
mid: 'ff.ff.ff.ff.ff.ff',
message: 'payload'
})
const results = await client.ft.search('idx:cits', '#mid:00.00.5e.00.53.af')
console.log(results)
await client.quit()
}
start(client)
Thank you!
The TEXT type in RediSearch is intended for full-text search—i.e. text meant for humans to read and not meant for computers to parse. So, it removes and doesn't search for things like punctuation—i.e. periods, colons, commas, etc.—and common words like a, and, or the.
You want to use a TAG type instead. You can think of these like a tag cloud on a blog post. A TAG field should contain a comma-separated string of values—the tags. If there's just a single value, it's just a CSV of one.
To create an index that uses a TAG field, do this:
await client.ft.create('idx:cits', {
mid: { type: SchemaFieldTypes.TAG },
timestamp: { type: SchemaFieldTypes.NUMERIC, sortable: true },
position: { type: SchemaFieldTypes.GEO }
})
To search a TAG field, use curly braces. Like this:
await client.ft.search('idx:cits', '#mid:{00:00:5e:00:53:af}')
Hope this helps.

How to iterate through querySelectorAll results in Nightwatch

I can't seem to find the correct syntax for iterating through the innerHTML of a nodelist in Nightwatch. I'm trying to return the urls of every 'a' tag contained within the body content of a page, but I can't find a way to access the results of my querySelectorAll command in Nightwatch.
browser.execute(function() {
return document.querySelectorAll("div.field-item.even a");
},
function(tags){
console.log(tags.value);
console.log(tags.value[9]);
})
There are 10 links on the page I am testing. The query selector seems to be retrieving them all, since console.log(tags.value) prints the following:
[ { ELEMENT: '1' },
{ ELEMENT: '2' },
{ ELEMENT: '3' },
{ ELEMENT: '4' },
{ ELEMENT: '5' },
{ ELEMENT: '6' },
{ ELEMENT: '7' },
{ ELEMENT: '8' },
{ ELEMENT: '9' },
{ ELEMENT: '10' } ]
and console.log(tags.value[9]) prints:
{ ELEMENT: '10' }
I cannot find a way to retrieve the link from these results, however. Appending .innerHTML to any of these variables returns 'undefined'. Is there any way for me to iterate through the querySelectorAll results and retrieve the urls inside of it?
EDIT: It seems like I can get the same result if I use the following code:
browser.elements("css selector", "div.field-item.even a", function(tags) {
console.log(tags.value);
console.log(tags.value[9]);
})
I originally thought that I was working with a nodelist, but I think I'm actually being returned a WebElement JSON object as per the documentation for the .elements command.
I'm still unable to access the inner text, however. Any ideas?
I resolved the issue using a different method. I used the browser.elements command instead of querySelectorAll, and then used browser.elementIdAttribute to get the contents of each 'href' attribute in each 'a' tag.
//Get an WebElement JSON object array of all urls
browser.elements("css selector", "div.field-item.even a", function(link_array) {
for (var x = 0; x < link_array.value.length; x++){
//Fetch the url from each 'a' tag in the content
browser.elementIdAttribute(link_array.value[x].ELEMENT, "href", function(links) {
console.log(links.value);
});
}
})
This prints out every link within the content of the page.
selectAllRoles: function (client) {
client.elements('css selector', '.editorDetail ul li input[type=checkbox]', function(res) {
res.value.forEach(elementObject => {
client.elementIdClick(elementObject.ELEMENT);
});
});
return this;
},
Fill in your id's after the 'css selector'

Sending a variable from express middleware to jade

I have a keystonejs app setup, using express and jade.
I have a fullscreen background image setup in my default.jade file which defines various imports and also the header and footer of the site.
I am trying to rotate the image based on a selection of images that are located in the mongodb via mongoose.
I was having issues getting it to work, so i have just been trying to get the variable to print correctly in the header of my page.
I have the following code setup in my root middleware file, as part of the export.initLocals file:
exports.initLocals = function(req, res, next) {
var locals = res.locals;
locals.navLinks = [
{ label: 'Home', key: 'home', href: '/' },
{ label: 'News', key: 'blog', href: '/news' },
{ label: 'Creations', key: 'creation', href: '/creations' },
{ label: 'Contact', key: 'contact', href: '/contact' }
];
locals.user = req.user;
locals.imageURL = 'variable set';
WelcomeImage = keystone.list('WelcomeImage');
WelcomeImage.model.findOneRandom(function(err, result) {
if (!err) {
locals.imageURL = result.Image.url;
console.log(result.Image.url); // 1 element
} else {
console.log(err); // 1 element
}
});
next();
};
and within my default.jade file i have:
//- HTML BODY
body
#background-image
//- HEADER
#header: .container
//- Customise your site's navigation by changing the navLinks Array in ./routes/middleware.js
//- ... or completely change this header to suit your design.
div(role="navigation").navbar.navbar-default
.container-fluid
.navbar-header
.visible-xs.navbar-brand-xs.a(href='/')
img(align:"left",src="/images/wild_logo.png",border=0,width=45,height=45)
button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
.collapse.navbar-collapse
.hidden-xs.navbar-brand.a(href='/')
img(align:"left",src="/images/wild_logo.png",border=0,width=95,height=95)
ul.nav.navbar-nav.navbar-left
each link in navLinks
li(class=(section == link.key ? 'active' : null)): a(href=link.href)= link.label
ul.nav.navbar-nav.navbar-right
if user
if user.canAccessKeystone
li: a(href='/keystone') Open Keystone
li: a(href='/keystone/signout') Sign Out
else
if imageURL
| #{imageURL}
else
There is no variable
//li: a(href='/keystone/signin') Sign In
//- BODY
#body
Now every time i load the page i see the variable rendered in the page, but it is set as 'variable set' and never get's set to the actual URL.
Now if i watch the console, the correct value is sent to the console on the line directly after it's set on locals.
So, any ideas what i'm doing wrong. I'm very new to express/jade so it's likely i'm overlooking something in the order things are done?
Thanks in advance!
Cheers
Gareth
Try moving next() inside the callback function of the findOneRandom call. You're basically telling node it's safe to move on before the callback is complete.
Glad that helped. Thanks!

How to add a new object to an array nested inside an object?

I'm trying to get a handle on using $resource in angularjs and I keep referencing this answer AngularJS $resource RESTful example for good examples. Fetching a record and creating a record work fine, but now i'm trying to add a "section" to an existing mongo record but can't figure it out.
documents collection
{
_id: 'theid',
name: 'My name",
sections: [
{
title: 'First title'
},
{
title: 'Second title'
}
]
}
angular controller snippet
var document = documentService.get({_id: 'theid'});
// TRYING TO ADD $scope.section TO THE SECTIONS ARRAY IN THE VARIABLE document.
//document.sections.push($scope.section); <-- This does NOT work
//document.new_section($scope.section); <-- could do this and then parse it out and insert it in my backend code, but this solution seems hacky and terrible to me.
document.$save(function(section) {
//$scope.document.push(section);
});
documentService
return $resource(SETTINGS.base + '/documents/:id', { id: '#id' },
{
update: { method: 'PUT' }
});
From the link i posted above, If I was just updating the name field, I could just do something like this:
var document = documentService.get({_id: 'theid'});
document.name = "My new name";
document.$save(function(section) {
//$scope.document.push(section);
});
I'm just trying to add an object to a nested array of objects.
Try this:
documentService.get({_id: 'theid'}, function(document) {
document.sections.push($scope.section);
document.$save();
});

Categories

Resources