Fork me on GitHub

I put some "initial data" inside the index.html. just moved from hiccup to fulcro.client.dom-server to generate my index.html. After this move I see that hiccup does not quote things. I was vulnerable to HTML injection attacks.


@U2J4FRT2T How did you add the intial-data ? did you use the ssr/initial-state->script-tag helper ?


😮 nope. I will look at it. ATM i'm not using SSR. I just generate a simple HTML with a greeting


I'm using "transit-string" inside a data-tag I think that it's better then a global JS var...


@grant did you make much progress with aws-amplify?


I'm trying to get Auth working, it correctly routes to the login screen, but the api calls and styling do not work.


What should the query be on a component that displays a list of entities, but where I do not want to tie it to a particular list? For example:

(defsc PersonList [this props]
  {:query [{:person/friends [:person/name]}]}})
with the above definition this component would be tied to ddisplaying a specific list, the person’s friends. How can I make a re-usable components to display any list so long at the items satisfy the sub-query :person/name?


there are a few ways to go about this, the simplest is just have one component for each list, you can even generate then programatically if you need to, I would think if you have that many kinds of list. but if you really want to change that, you can take a look at dynamic queries, with those you can dynamically compute the query, so you can chance as you wish


can you tell more about for what case you like to keep this variable?


@wilkerlucio in think in my scenario having a component per list is perfectly acceptable, in fact right now I will only have one such components. But writing this component begged the question, so I thought I would ask 🙂


I can understand, its good when you know its possible, even when in reality you will hardly need it 😛


In GraphQL/Relay/Apollo (which I am used to), it’s common to have a list component expose a query for the elements (.e.g the PersonList would expose a query for a Person), then whichever component is using that list can compose in the Person query when querying for the list data


if you see what I mean


you still get that, but even on graphql you still have to define the list name in the parent, right? or do you use the list name as a variable too there?


It’s taking me a bit of getting used to with Fulcro. Another scenario I was thinking of the other day was a component who needs to display two bits of data that don’t live on the same node


even if they dont you can always make a link to it


or use some globals, in fulcro your component can point to any global table with the syntax: :query [[:root-table '_]]


@wilkerlucio what do you mean by that? The parent might have the list name, yes. So you could have a generic PersonList component, then on the parent use it as <PersonList items={friends} />, where you composed the PersonList.person query when fetching the friend data


then you :root-table key in the props, with that global value


@wilkerlucio ah yes, but I meant generic component (in the same way as the list component here). For example, a generic component to compare two Person objects.


yup, you could write a component that points to two person instances, you can make up as many names as you want, you just need to make a way to "select" those items, using a mutation for example, you can change the db of a ui component to have the pointers, makes sense?


something like:


{:ident [:ui/id :ui/id]
 :query [:ui/id
         {:ui/person-a (fp/get-query Person)}
         {:ui/person-b (fp/get-query Person)}]}


@wilkerlucio but for that you would need dynamic queries, right? I get how you can make a component that points to two person instances (given IDs), but you can’t pass two instances as props, right?


no need for dynamic, just a new component to accommodate the relationships


but then whatever component is using this “comparison” component will need to compose the Person query, right? Not the comparison component’s query?


depends on when you want to setup the relationship


we can think of a list of products that the user will select to compare


at first, the compare component will have nothing, because user didn't selected anything


then by interacting you can make those links, so the component has the correct selection that was driven by the user


in case the comparison should start there, this means your server must know about it, so you could use pathom to write rules that define to which things it should point


so in the end is just about giving a name and fulfilling it at appropriated time, makes sense?


@wilkerlucio I think I didn’t express myself properly. What i meant is this: if you have a hierarchy of 3 nested components, say App > ProductCompare > Product. When you fetch the list of products on App (as part of App’s query), you will need to compose in the query of the Product component. But the App component itself doesn’t use the Product component, it’s essentially an implementation detail of the ProductCompare component (which App uses). As far as I can see, there is no way for the ProductCompare component to communicate to App the query it needs on a product.


we are thinking something fundamentally different I guess, lets get concrete, in the case of product compare, some context will have to be known to define which items it should load to compare at first, right? if you can give me a concret case we can work it out


from what you describe this is what I imagine as a base scaffold:


(fp/defsc Product
  [this {::keys []}]
  {:ident [:product/id :product/id]
   :query [:product/id :product/name]}

(fp/defsc ProductCompare
  [this {::keys []}]
  {:ident []
   :query [
           { (fp/get-query Product)}
           { (fp/get-query Product)}]}

(fp/defsc App
  [this {::keys []}]
  {:ident [:app/id :app/id]
   :query [:app/id
            (fp/get-query ProductCompare)}]}


@wilkerlucio I’ll apply your advice of sticking to non-generic components for now; I don’t want to waste your time with theoretical discussions if I don’t have a specific issue to solve. My specific issue tonight was rendering a generic list, but in my case I can get away with a non-generic list.


no worries, I find nice to go over those things from time to time 🙂


@wilkerlucio ah I see, maybe I am just thinking about this wrong. In the example you gave me you are basically making a “product comparison” an actual bit of data


I was just thinking of it as two props (the two products) that you pass in, without those two props living on an object (a product comparison)


yup, because any context needs something to hold it, it could be persistent or not, but at some point you will need something to hold then, its just that fulcro encourages (kind forces :P) you to makes that explicit


That makes sense. This solution can’t be applied to my “generic list” issue though, right? i.e. have a PersonList component that I can then use to render a person’s friend list, a person’s enemies list, etc


no, you can't, but in practice there is a simple solution, wrap whatever is generic in separated functions and make up more components that look very equal but the list name they are using on their own query


they get very short and keep things consistent and easy to follow


makes sense. So the “specific” list components are basically one-liner excluding the query


when you make things more dynamic/generic you should also think of the price on navigability, in big code makes that can make a big difference


they are only there to query for data and delegate the rendering to the generic function


That makes sense. Thanks a lot 🙂


@wilkerlucio While I am at it, I have another quick question that came to mind after reading part of the Pathom doc. In Pathom it seems like you have the ability to specify a union-path, so that you can switch over a :type field, for example. In Fulcro unions seem to work differently (based on the table name). Is there a union-path equivalent in Fulcro?


there is no union-path in fulcro, unions there work in a specific way, based on ident, so you must end up with different idents


but even in pathom I still use something that's similar to the fulcro idea


most of the time when I make an union I make the selection to be based on the item having the key associated with the component ident


works pretty well 🙂