Using 3rd party API data across pages in Bubble

Hello, Bubble World! I am creating an online menu using a GraphQL API as my data source. I’ve been successful in connecting up to it and pulling data into existing Bubble templates but I’m struggling to figure out how to send data from page to page. For example, I have a RepeatingGroup element with cells that show 4 different products and their images and other relevant details. What I want is for a user to be able to then click on the product and the product they clicked on show up in the product detail page (for which there is also an existing template). But, I’m struggling on how do this because the template page as a content type and it doesn’t appear as if the 3rd party API can be designated as a content type for a page. Am I thinking about this correctly? Any leads would be helpful.

There’s a few ways to do this, but it all starts with the workflow that triggers when the user clicks on the repeating group element.

Screen Shot 2022-01-09 at 12.24.43 pm

  1. You could send the product data using the “data to send” field. Here’s a tutorial on how that works: Learn | Bubble Editor

The downside of this method though is that it’s like using a page state and when the page is reloaded or if the user bookmarks it for later, the data is lost and you’ll have an empty product page.

  1. You could send a page parameter, and then use that page parameter on the other end to populate the page. This would be an easy & free approach. You URL will look something like example.com/product?id=12345

  2. My preferred way to do this would be to use a plugin like sudsy where you can easily set the path to whatever you like. i.e Sudsy would allow you to rewrite the URL above to something like example.com/product/12345.

I use this plugin a lot as I often build one page apps or at least group areas of my app together on a single page for a more native experience. But in your case, even if you don’t have a one page app you can still limit the number of page reloads. i.e. if you have a “similar products” or something section at the bottom you could use sudsy to rewrite the URL to the new product and then the page content will change accordingly without needing to reload the page.

1 Like

Thanks @josh24. The URL parameter method makes sense and I would have spent too much time down the rabbit hole on the “data to send” field otherwise.

I spent some time toying around sending the parameters but I’m now struggling on the “receiving end” on how to populate the product page type with this. I’ve read several tutorials now on using the URL parameters in Bubble navigation but I can’t seem to land on how to populate the product page with the URL parameters.

For example, I set a parameter to be sent over on the group item click to the product page with a key of “product” and a dynamic value of “Current cell’s Product Id” and this acts as expected. When I test the app and click the Group Item, it opens the product page and the URL has the parameter and the correct product id populated for the item that was clicked.

But, I can’t figure out how to get the product page to “read/lookup” this parameter and thus only show information for that particular product. The template I’m using easily does it because its products are coming from the Bubble database, and thus, the whole product page’s content type is “product”.

I’ve tried the following in my application using the parameterization you wisely suggested but have been unsuccessful:

Setting the group element’s data source to a filter that matches the product ID (but I just keep getting a warning that the template I’m using expects a singular item, probably because the product detail group on the page isn’t a repeating group?). I used the expression of the data source and then :filter and tried to filter to the parameter of the product ID. But maybe I’m supposed to do this in a workflow on the page instead of on the actual group element data source?

Thanks again for starting me down a good direction and grateful for any additional wayfinding/pointers you have.

@josh24 I was trying to replicate the logic used in the following link (but for an external database API as noted in the original post):

So there would be a few steps

  1. You have an existing API call that would return your list of products in the external database - which is fine. You will now need to create an additional API call in the API connector that would bring back the details of just one product, which you can call from the product details page. You could use the same API call that’s already configured and filter it to just the product you want (as suggested), but it’s an incredibly inefficient way.

Reason being is if you’ve got 100 products, you’ll essentially download the data of 100 products each time the product page is opened only to disregard 99 of them. Your app performance will suffer a lot.

You may also want to limit the API call used for the repeating group to just the fields you need to show in the repeating group for the same reason, and include the additional fields - i.e. additional images, product description, any additional fields that are shown on the detail page.

  1. You can then make a single call to the API (the new API call you’ve configured in step 1) and then everything on the page that is dynamic can reference that. The best way to do this:

2.1 Create a popup. Popups are a great way to have hidden variables on your page that you can reference. Create a group inside the popup that you can reference as the data source.

2.2 Set the data type to the API call (new API call for a singular product) and then in the data source select “get data from external API” and select the API call. Name the group something memorable like “var - product”.

2.3 You should have a parameter in your API call for the product ID, so you’ll need to set the parameters to make the call. In the product ID field you can use “Get data from page URL” to reference the URL parameter.

Screen Shot 2022-01-09 at 4.02.42 pm

2.4 You should be now able to reference the “var - product” group from text fields, images or whatever and populate your page.

I’m not sure of your Bubble skills, but this is a very high-level steer. Hope it helps

Cheers,
Josh

2 Likes

@josh24 Thanks for the response and for taking the time to spell out the steps – I feel like I’m almost there and learning a ton along the way. I was successful in completing the pop-up trick and pulling in data using it on one particular product (after re-writing the API call). I’m stuck on 2.3 – and I’m not sure if it’s because I’m having to use a GraphQL API call rather than a normal REST one or not.

In step 2.3, where do you suggest placing this parameter in the API call? I’ve tried setting the parameters in the what I think is the “normal” way at the top of the API call but that hasn’t been successful in returning data. Only when I set them in the “Body parameters” have I been successful in returning data. In the body JSON code, I have included <> to indicate a dynamic value for product Id. If I don’t fill the value field out when I initialize the call, I get all errors returned (which I don’t think I want). But, if I fill out the value with a productID then I can’t figure out how to get the URL parameter to populate this dynamic field within Bubble.

Successful API Call:

{"query":"query fetchProduct {\n product(id: \"<productId>\" retailerId: \"<retailerId>\") {\n name\n brand {\n name\n }\n category\n description\n Type \n variants {\n option\n priceNorm\n priceTwo\n specialPriceNorm\n specialPriceTwo\n }\n }\n}\n\n\n\n\n\n\n\n\n","variables":{}}

Unsuccessful API Call:

{"query":"query fetchProduct {\n product {\n name\n brand {\n name\n }\n category\n description\n Type \n variants {\n option\n priceNorm\n priceTwo\n specialPriceNorm\n specialPriceTwo\n }\n }\n}\n\n\n\n\n\n\n\n\n","variables":{}}

Thanks again for your guideposts.

So I’ve only played around once with integrating a GraphQL API in the Bubble API connector and had the same issue where I had to put the payload in the body JSON to get it to work. I believe this has to do with the structure of a GraphQL call vs a REST call and the Bubble API connector is designed for REST APIs. But it’s not too much of a drama.

  1. To get the API call to work, you will need to populate it with data and make a successful call for it to initialise and be available to workflows

  2. When you have a payload in the body of the call you should be able to dynamically change this body when you create your workflow. i.e. You can see how I have done this for an API call

Screen Shot 2022-01-10 at 12.38.36 pm

  1. Not relevant to this situation as you’ll need to remove the parameters. But for any other REST API integrations you try to do, you’ll need to remember to uncheck the Private checkbox for those fields you wish to dynamically change in a workflow. If you set them to private they will be static. So you’d set any static fields to private so they don’t need to be configured in a workflow / you won’t want to be accessible from the front end. And then you’ll set anything that should be dynamically set to not private

@josh24 I’m afraid you’ve lost me with this last bit and how it relates to the earlier suggestions, very much likely to my beginner status in both Bubble and APIs. In recapping, I think where I’m at is that on my index page in a RepeatingGroup I am defining a workflow where when an item of that group is clicked on, it is sending URL parameters with the productID of that item to a products page. This has been completed successfully. But, on the products page I still haven’t been able to “read” this passed URL parameter into an API call for that particular product. The last image you shared here with the dynamic updates to the API Body – what workflow action is this? I can’t seem to find it. Does this new information mean your original suggestion of how to get this info (i.e., the popup approach) isn’t viable? It seems like a different approach but, given my novice status, not entirely sure of conclusion. Thanks for the high-level steering. I think maybe this is where my training wheels crumple a bit… haha