SwiftUI - How to make NavigationView not affect geometry reader's location - swift

I'm trying to get the position of a scrollview using a geometry reader. However, I've noticed that it gives me a different value depending on if I have it embedded in a NavigationView or not. Here is an example:
struct ContentView: View {
#State var headerLocation: CGFloat = 0
var body: some View {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
let minY = geo.frame(in: .global).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
GeometryReader { proxy -> Color in
let offset = proxy.frame(in: .global).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
}
}
}
}
}
}
The code above functions like intended. When the app is started, it sets the location of the blue rectangle at the top of the screen. If we scroll the scrollview, we can see that the number is equal when we scroll the green rectangle to the same location as the blue one.
Now take the code below:
struct ContentView: View {
#State var headerLocation: CGFloat = 0
var body: some View {
NavigationView {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
let minY = geo.frame(in: .global).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
GeometryReader { proxy -> Color in
let offset = proxy.frame(in: .global).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
}
}
}
}
.navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
}
}
}
When we try to do the same thing, we can see that when the green rectangle is at the same location as the blue one, they have different values. How can I achieve the functionality of the first code block while keeping a NavigationView? I've already tried the different NavigationBarDisplayModes and NavigationTitles

Let me introduce you to .coordinateSpace() where you can pick the view you want to use to compare GeometryReaders. Simply put, as you can see, the NavigationView is messing with the values in the GeometryReaders, so since they both exist in the ZStack, we can easily compare them there. The trick is telling the GeometryReaders what view to use. We do this with .coordinateSpace() placed on the ZStack, and then, instead of using .global() we use .named(). I have abbreviated your Text() to make it shorter and clearer. Here is the code at work:
struct ContentView: View {
#State var headerLocation: CGFloat = 0
var body: some View {
NavigationView {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
//Use .named() instead of .global()
let minY = geo.frame(in: .named("ZStack")).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem.")
GeometryReader { proxy -> Color in
//Use .named() instead of .global()
let offset = proxy.frame(in: .named("ZStack")).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem.")
Text("Lorem.")
Text("Lorem.")
Text("Lorem.")
}
}
}
}
// Put the .coordinateSpace here. The name can be any hashable value.
.coordinateSpace(name: "ZStack")
.navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
}
}
}

Related

Flutter - I want to show only first 2 Paragraphs

So I have a Big passage with like 8 Paragraphs. But I only want to show the first 2 paras.
Let's take the below example:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque et urna id porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer vitae auctor diam. Curabitur ipsum turpis, porta sit amet lorem sit amet, ultricies gravida turpis. Mauris congue purus nec tortor laoreet, eu rutrum ligula egestas. Morbi ut magna sapien. Aliquam malesuada velit nec lorem ultricies facilisis. Praesent imperdiet porttitor sodales.
Proin vel arcu purus. Ut nulla lectus, mattis nec condimentum quis, vulputate ac lacus. Suspendisse potenti. Duis consectetur ante ac ultricies sagittis. Donec finibus tortor eu nibh volutpat, non tincidunt nibh malesuada. Nunc sit amet purus vel arcu facilisis facilisis. Pellentesque felis nunc, bibendum fringilla auctor a, varius sit amet nibh.
Maecenas scelerisque, lacus eu gravida fermentum, magna magna finibus urna, eu pulvinar nisl nisi sed velit. Sed in iaculis lacus, sed ornare ipsum. Fusce commodo risus quis arcu volutpat, vitae sollicitudin dolor pellentesque. Phasellus lacus quam, placerat eu lorem vitae, congue accumsan metus. Fusce ultricies vehicula tempus. Aenean a urna tempus, eleifend felis et, venenatis justo. Aliquam quis dapibus risus. Nunc gravida sodales metus, eget aliquet nunc vestibulum vitae. Donec semper finibus ex ac elementum. Maecenas sed nulla id tellus viverra tincidunt quis sed leo. Fusce quis condimentum elit. Donec ultricies imperdiet pulvinar. Nunc egestas quis leo eu cursus. Sed faucibus, enim non dictum commodo, velit felis maximus risus, ut hendrerit dui augue vel justo.
I am getting this data from an API. I only want to show the first 2 paragraphs starting with Lorem ipsum & Proin vel respectively.
I have no idea how to do this. I tried searching the web but did not find any useful information.
var p = text.split('\n\n').take(2);
or if it's needed to join into single string
var p = text.split('\n\n').take(2).join('\n\n');
The Text Widget has the property of max lines you can use it to specify how many lines from a paragraph should be shown. And there is a text-overflow property that can help you get more control over it. Following is an example.
Text(
"This is a long text",
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),

Migration Script is creating foreign key constraint but not generating value from reference column

System information:
Operating system (distribution) and version: Mac Catalina
DBeaver version: 7.1.2
Database name and version: Postgresql
Express Server
VSCode
I have been working with 2 tables. The first table's id needs to be linked by foreign key to the second table's "folder_id". My migration script created the tables as planned. When seeding the database, I am unable to get the values from the foreign key constraint to propagate from the reference column (id) in the (folder_id) column. Currently the "folder_id" column is saying NULL after I seed the database. I am trying to get the values in folder_Id to be the values from the id column in the folders table
here is a screenshot of both tables: view of both tables in DBeaver.
Here is the migration script I used:
CREATE TABLE noteful_folders (
id int4 PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
hex_id VARCHAR,
title TEXT NOT NULL
);
CREATE TABLE noteful_notes (
id INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
hex_id VARCHAR,
title TEXT NOT NULL,
modified TIMESTAMPTZ DEFAULT now() NOT NULL,
folder_hex_id VARCHAR,
folder_Id int4,
content TEXT
);
ALTER TABLE noteful_notes ADD CONSTRAINT note_fk FOREIGN KEY (folder_id) REFERENCES public.noteful_folders(id);
Here are the two seed scripts I used:
notes seed:
INSERT INTO noteful_notes (hex_id, title, modified, folder_hex_id, content)
VALUES
('cbc787a0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Dogs', '2019-01-03T00:00:00.000Z', 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0034-ffaf-11e8-8eb2-f2801f1b9fd1', 'Cats', '2018-08-15T23:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e01a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Pigs', '2018-03-01T00:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0570-ffaf-11e8-8eb2-f2801f1b9fd1', 'Birds', '2019-01-04T00:00:00.000Z', 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0714-ffaf-11e8-8eb2-f2801f1b9fd1', 'Bears', '2018-07-12T23:00:00.000Z','b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0854-ffaf-11e8-8eb2-f2801f1b9fd1', 'Horses', '2018-08-20T23:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0980-ffaf-11e8-8eb2-f2801f1b9fd1', 'Tigers', '2018-03-03T00:00:00.000Z', 'b07162f0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0aac-ffaf-11e8-8eb2-f2801f1b9fd1', 'Wolves', '2018-05-16T23:00:00.000Z','b07162f0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0bce-ffaf-11e8-8eb2-f2801f1b9fd1', 'Elephants', '2018-04-11T23:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e0f48-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lions', '2018-04-26T23:00:00.000Z', 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e1074-ffaf-11e8-8eb2-f2801f1b9fd1', 'Monkeys', '2018-02-05T00:00:00.000Z', 'b07162f0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e11a0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Bats', '2018-12-01T00:00:00.000Z', 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e12c2-ffaf-11e8-8eb2-f2801f1b9fd1', 'Turtles', '2018-09-11T23:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.'),
('d26e1452-ffaf-11e8-8eb2-f2801f1b9fd1', 'Zebras', '2018-08-13T23:00:00.000Z', 'b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum suscipit blandit purus convallis vehicula. Vestibulum enim augue, auctor a diam eget, scelerisque laoreet eros. Proin id maximus nisi, sed rhoncus mi. Suspendisse eu arcu volutpat, tempor nisl at, pretium erat. Nullam a elementum lorem. Mauris aliquam ante a libero eleifend pretium. Donec ante odio, consectetur vel nisl quis, semper bibendum velit. Sed magna turpis, placerat eget arcu vitae, pellentesque dignissim mi. Nunc ullamcorper dolor mi. Ut tortor orci, laoreet et vestibulum a, ornare sed quam. Integer id quam dui. Fusce et consectetur nulla. Suspendisse rhoncus posuere augue id mattis.');
folders seed:
INSERT INTO noteful_folders (hex_id, title)
VALUES
('b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1', 'Important'),
('b07161a6-ffaf-11e8-8eb2-f2801f1b9fd1', 'Super'),
('b07162f0-ffaf-11e8-8eb2-f2801f1b9fd1', 'Spangley');
My question: what would I need to do to get the folder_id column in the notes table to reflect the values from the id column in the folders table? Do I need to put a placeholder of some sort inside the seed script for the notes table to get the values to populate correctly from the folder table's id column?
First, you should not link screenshots. Can you please paste the text from your screenshots as text into code blocks in your answer?
The folder_hex_id column in table noteful_notes violates the principle of relational theory. The noteful_notes table should contain only the folder_id column. Oddly, your model's violation of this principle makes it very simple to fix the already seeded data. Issuing this will correct your data, but this is absolutely not the right way to do your seeding.
update noteful_notes
set folder_id = f.folder_id
from noteful_folders f
where f.hex_id = noteful_notes.folder_hex_id;
I assume you are not using an ORM, and please do not correct me if I am wrong since ORMs are the devil :-)
My suggestions are for you to remove the folder_hex_id column from noteful_notes, define folder_id in noteful_notes as folder_id not null references noteful_folders(id), make your seeding procedure load noteful_folders before loading noteful notes, and seed your noteful_notes table thusly:
with indata (hex_id, title, modified, folder_title, content) as (
values ('<your note hex id1>', '<your note title1>', '<your timestamp1>',
'<your folder title1>', '<your post content>1'),
('<your note hex id2>', '<your note title2>', '<your timestamp2>',
'<your folder title2>', '<your post content2>')
)
insert into noteful_notes (hex_id, title, modified, folder_id, content)
select i.hex_id, i.title, i.modified, f.id, i.content
from indata i
join folder f
on f.title = i.folder_title
;
I assume you have a good reason for keeping hex_id values with your notes and folders. Please mention in the comments if you do not have a good reason.
If you would rather link the notes to the folders with the hex_id in your data, then it should be pretty clear how to substitute folder_hex_id for folder_title.

How can I change the data in an object in MongoDB?

My desired end result is to change the data in an object in MongoDB using Hyper as my terminal. So far, this is the context of what I'm talking about: the DB, the collections, and the objects.
My database...
> show dbs
blogDB 0.000GB
Using my database...
> use blogDB
switched to db blogDB
My collection...
> show collections
posts
My objects...
> db.posts.find()
{ "_id" : ObjectId("5f00acc1324fc732401ad2f2"), "title" : "Day 1", "content" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "__v" : 0 }
{ "_id" : ObjectId("5f013318f1fbfe63547d34a6"), "title" : "Day 2", "content" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "__v" : 0 }
{ "_id" : ObjectId("5f01338c8d56ee5070ccd331"), "title" : "Day 3", "content" : "Mattis nunc sed blandit libero volutpat sed cras. Lectus vestibulum mattis ullamcorper velit. Eget mi proin sed libero enim sed faucibus turpis. Dui accumsan sit amet nulla facilisi morbi tempus. A condimentum vitae sapien pellentesque habitant morbi tristique. Nunc sed id semper risus in hendrerit. Odio pellentesque diam volutpat commodo. Nunc lobortis mattis aliquam faucibus purus. Nec nam aliquam sem et tortor consequat id porta. Pellentesque id nibh tortor id aliquet lectus proin nibh nisl. Urna et pharetra pharetra massa massa ultricies
mi.", "__v" : 0 }
What I've tried to use to achieve my desired end result and what occurred when I attempted it...
> db.posts.updateOne({title: Day 2}, {$set: {content: Sed risus pretium quam vulputate. Nec ullamcorper sit amet risus nullam eget felis. Sit amet mattis vulputate enim nulla aliquet. Nulla pharetra diam sit amet nisl suscipit adipiscing bibendum est. Scelerisque felis imperdiet proin fermentum. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Phasellus faucibus scelerisque eleifend donec. Arcu cursus vitae congue mauris rhoncus. Faucibus scelerisque eleifend donec pretium. Nunc lobortis mattis aliquam faucibus purus in. Vitae auctor eu augue ut lectus. Lectus mauris ultrices eros in cursus turpis massa.}})
2020-07-05T21:04:04.747-0400 E QUERY [js] uncaught exception: SyntaxError: missing } after property list :
#(shell):1:31
> db.posts.updateOne({_id: ObjectId("5f013318f1fbfe63547d34a6")}, {$set: {content: Sed risus pretium quam vulputate. Nec ullamcorper sit amet risus nullam eget felis. Sit amet mattis vulputate enim nulla aliquet. Nulla pharetra diam sit amet nisl suscipit adipiscing bibendum est. Scelerisque felis imperdiet proin fermentum. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Phasellus faucibus scelerisque eleifend donec. Arcu cursus vitae congue mauris rhoncus. Faucibus scelerisque eleifend donec pretium. Nunc lobortis mattis aliquam faucibus purus in. Vitae auctor eu augue ut lectus. Lectus mauris ultrices eros in cursus turpis massa.}})
2020-07-05T21:11:53.463-0400 E QUERY [js] uncaught exception: SyntaxError: missing } after property list :
#(shell):1:85
> db.posts.replaceOne({_id: ObjectId("5f013318f1fbfe63547d34a6")}, {$set: {content: Sed risus pretium quam vulputate. Nec ullamcorper sit amet risus nullam eget felis. Sit amet mattis vulputate enim nulla aliquet. Nulla pharetra diam sit amet nisl suscipit adipiscing bibendum est. Scelerisque felis imperdiet proin fermentum. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Phasellus faucibus scelerisque eleifend donec. Arcu cursus vitae congue mauris rhoncus. Faucibus scelerisque eleifend donec pretium. Nunc lobortis mattis aliquam faucibus purus in. Vitae auctor eu augue ut lectus. Lectus mauris ultrices eros in cursus turpis massa.}})
2020-07-05T21:51:29.498-0400 E QUERY [js] uncaught exception: SyntaxError: missing } after property list :
#(shell):1:86
I also attempted to delete the object so that I could just create a new one in its place. This was the result...
> db.posts.deleteOne({title: Day 2})
2020-07-05T21:08:33.748-0400 E QUERY [js] uncaught exception: SyntaxError: missing } after property list :
#(shell):1:31
Also, to give further clarification (if necessary): this is the database for a website I developed using MongoDB, Mongoose, NodeJS, Javascript, Express and EJS. This website is a simplified blog website which allows a person to compose a new blog post (via a compose page) which is then added to the aforementioned MongoDB.
This website (currently) does not have a 'delete' or 'edit' button/page - something I'm likely to add in the future. For now, any editing or deleting of posts must be done via MongoDB via a terminal (like the Hyper terminal I'm using).
With that said, I greatly appreciate any help. If there's any further clarification or needed information please feel free to ask. I'm still very much a newbie so I'll do my best to answer as clearly as I can muster.
UPDATE:
Following a suggestion from #thammada.ts I added quotes around the data that was a String type which solved my problem and this was the result...
> db.posts.updateOne({_id: ObjectId("5f013318f1fbfe63547d34a6")}, {$set: {content: "Sed risus pretium quam vulputate. Nec ullamcorper sit amet risus nullam eget felis. Sit amet mattis vulputate enim nulla aliquet. Nulla pharetra diam sit amet nisl suscipit adipiscing bibendum est. Scelerisque felis imperdiet proin fermentum. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Phasellus faucibus scelerisque eleifend donec. Arcu cursus vitae congue mauris rhoncus. Faucibus scelerisque eleifend donec pretium. Nunc lobortis mattis aliquam faucibus purus in. Vitae auctor eu augue ut lectus. Lectus mauris ultrices eros in cursus turpis massa."}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
According to thammada.ts:
You have to put quotes around values that are strings, such as "Day 2", just like how they are represented when you run db.posts.find()

MongoDB indexes for field existence?

Say I have a collection with millions of documents, some of which have a field like myField in the example below:
{
...
myField: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse suscipit, lectus pharetra sodales cursus, purus nunc tristique urna, vel bibendum purus nisl non ipsum. Aenean porta porttitor mauris, vitae bibendum augue luctus vitae. Fusce non posuere quam. Mauris bibendum elit orci, et pretium quam faucibus sit amet. Vivamus nec congue sem, in commodo nisi. Pellentesque dapibus neque eget sem elementum, non pellentesque erat sagittis. Morbi et scelerisque orci. Etiam sed augue orci. Aliquam feugiat, arcu non aliquet sagittis, ante enim lacinia purus, quis lacinia leo leo id diam. Curabitur rutrum, eros in gravida efficitur, justo sem finibus dui, at lacinia nulla neque non nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse suscipit, lectus pharetra sodales cursus, purus nunc tristique urna, vel bibendum purus nisl non ipsum. Aenean porta porttitor mauris, vitae bibendum augue luctus vitae. Fusce non posuere quam. Mauris bibendum elit orci, et pretium quam faucibus sit amet. Vivamus nec congue sem, in commodo nisi. Pellentesque dapibus neque eget sem elementum, non pellentesque erat sagittis. Morbi et scelerisque orci. Etiam sed augue orci. Aliquam feugiat, arcu non aliquet sagittis, ante enim lacinia purus, quis lacinia leo leo id diam. Curabitur rutrum, eros in gravida efficitur, justo sem finibus dui, at lacinia nulla neque non nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse suscipit, lectus pharetra sodales cursus, purus nunc tristique urna, vel bibendum purus nisl non ipsum. Aenean porta porttitor mauris, vitae bibendum augue luctus vitae. Fusce non posuere quam. Mauris bibendum elit orci, et pretium quam faucibus sit amet. Vivamus nec congue sem, in commodo nisi. Pellentesque dapibus neque eget sem elementum, non pellentesque erat sagittis. Morbi et scelerisque orci. Etiam sed augue orci. Aliquam feugiat, arcu non aliquet sagittis, ante enim lacinia purus, quis lacinia leo leo id diam. Curabitur rutrum, eros in gravida efficitur, justo sem finibus dui, at lacinia nulla neque non nulla.",
...
}
I would like to be able to perform a query that returns records where the field myField exists. I can do this by creating an index on myField, but the index is quite large and is really being underutilized since I am only checking for field existence.
Is there a way to create an index that would only be used to check if the field exists (and not value matching)? I looked into partial indexes, and while interesting, I can't see how they would apply here.
It looks like you are looking for Sparse indexes

KRL: Truncating a string

I'm pulling in an RSS feed from a Tumblr blog. Unlike WordPress, which gives a condensed version of the post in the <description> tag, Tumblr dumps the whole post into the feed with no shortened version at all. I'd like my Kynetx app only to output the first, say, 400 characters if the post is longer than that.
I could emit some JavaScript to do it, something like this:
if (post.length > 400) {
post = post.substring(0, 400);
}
Is there a way to do something like that in KRL directly?
Yes! You can use the extract function which will return an array of matches from a Regex.
Extract function documentation
truncated = originalString.extract(re/^.{100}/gi);
Example Appruleset a60x549 {
meta {
name "string-truncate-test"
description <<
string-truncate-test
>>
author "Mike Grace"
logging on
}
rule testingerlyish {
select when pageview ".*"
pre {
originalString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam id purus quis urna aliquam volutpat. Nullam ut velit enim. Cras eu libero felis, vitae adipiscing dolor. Mauris metus nisi, facilisis vitae hendrerit a, posuere in nisi. Integer convallis, odio eu ultrices luctus, arcu ligula ultrices neque, sit amet aliquet lorem diam eget ipsum. Morbi ullamcorper feugiat urna sagittis volutpat. Nullam tincidunt gravida sem, vel suscipit quam cursus egestas. Etiam quis felis leo, id blandit metus. Vestibulum lacinia tortor sit amet mi consectetur non malesuada arcu hendrerit. In placerat mauris nec quam dictum eleifend. Suspendisse consectetur rutrum mauris id vestibulum. Vivamus dignissim imperdiet lorem sit amet eleifend. Etiam nulla est, feugiat non accumsan egestas, luctus in nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras orci libero, aliquet id ultricies id, tempor eu eros. Suspendisse ultricies enim quis dui malesuada condimentum. Sed in est velit, ac volutpat velit. Nunc aliquet commodo pellentesque. Curabitur egestas, nibh sed dapibus imperdiet, urna nisi ultricies justo, nec dictum nulla est vitae lectus. Morsapien purus tincidunt nulla, sit amet sodales nisi mi sit amet purus. In facilisis ligula vitae sapien aliquet condimentum. Integer lacus dolor, tincidunt dapibus consequat id, luctus et erat. Praesent vel nunc enim. Donec dignissim dui tincidunt lacus molestie in laoreet ligula placerat. Nullam elit magna, luctus sit amet vestibulum ut, dignissim eget elit. Pellentesque nunc massa, auctor sit amet venenatis sed, hendrerit eu nibh. Vestibulum in nisi purus, eget dictum velit. Phasellus pulvinar odio sed nulla egestas lacinia. Donec porttitor lobortis porta. Nullam imperdiet dapibus pulvinar. Sed ut quam tellus. Sed ornare vulputate facilisis. Suspendisse potenti. Nullam aliquet nulla id enim suscipit iaculis pellentesque lectus vulputate. Cras ullamcorper nunc nec eros porta quis fermentum lectus mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas ac imperdiet nisi. Morbi nec elit in eros varius luctus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque aliquet, elit et mattis dignissim, metus tortor fringilla mauris, fermentum bibendum metus mi et lorem. Ut at magna quam, ac condimentum ipsum. Aenean aliquam elementum nisl vitae tempus. Fusce molestie, metus nec egestas facilisis, velit turpis bibendum quam, nec blandit arcu leo non ligula. Morbi nisl neque, gravida in pulvinar ut, sollicitudin eu nunc. Phasellus eget sagittis nunc. Praesent nibh libero, lacinia placerat fermentum a, fringilla sit amet mi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed odio dolor, dignissim a dictum ut, fringilla sit amet purus. Duis et justo et felis tempus pulvinar id eget odio. Suspendisse ac turpis sit amet orci laoreet cursus. Aliquam at odio quis massa pulvinar sollicitudin. Cras nec laoreet metus. Mauris consectetur mauris sit amet nulla rutrum quis tristique erat placerat. Phasellus id felis enim, et molestie dolor. Maecenas dignissim faucibus augue vitae pulvinar. Pellentesque auctor massa eu massa sagittis rutrum. In varius dignissim odio, eu .";
truncated = originalString.extract(re/^.{100}/gi);
}
{
notify("Truncated",truncated[0]) with sticky = true;
}
}
}
Example app run on example.com using bookmarklet: