Search code examples
javascriptarraysjsonbuildprerender

Project works fine on localhost but the build gets an issue


I am working on a Preact-CLI project with a Preact-Router and it works fine on the localhost. But the production doesn't work well after the build.

I have created a one page object which gets its content dynamically from a JSON file (inside the project not external). So I've loaded the same page object 2 times for each different page.

I get the page url (using this.props.permalink) and compare it with the JSONObject.title. If they are the same I want to get the corresponding JSON content to display it on the corrrct page. Works like a charm on localhost, but not in production.

Issue: Somehow all pages get the content of the first JSON element. First I thought it was a server issue but I was wrong. The builded files are wrong after the prerendering/build. So the prerendered html of page B contains the content of the prerendered page A. My guess is that during the build this.props.permalink doesn't work. How should I handle this?

Additional info: I use the prerender function but not the service worker for the build.

Thanks!

UPDATE: I have rewritten the function. I guessed I needed to set the dynamic content through a loop, so that during the build the compiler loops through it and is able to prerender all the pages.

The iteration and setting the state works, but only the final element of the PrerenderUrls array gets stored. So now all pages gets the JSON content of the first element.

componentWillMount() {


        for (var i = 0; i <= PrerenderUrls.length; i++) {

            // the code you're looking for
            let removeDash = new RegExp("-")
            var needle = PrerenderUrls[i].title
            var needle1 = needle.replace(removeDash, " ")
            alert("1")


            // iterate over each element in the array
            if (needle1 != "Homepage") {
                for (var x = 0; x < Data.length; x++) {

                    // look for the entry with a matching `code` value
                    let removeDash = new RegExp("-")
                    var nodash = Data[x].title.replace(removeDash, " ")
                    var nocaps = nodash.toLowerCase()
                    if (nocaps == needle1) {

                        alert("needle2: "+ needle1 + " nocaps: " + nocaps)
                        //alert("data "+ Data[x].title)
                        this.setState({
                            pageTitle: Data[x].title,
                            descShort: Data[x].descShort,
                            description: Data[x].desc,
                            img: Data[x].img
                        })
                        alert("state "+ this.state.pageTitle)
                    } 
                } 
            }
        }

Solution

  • From your description it seems you have a standard Javascript closure problem. I noticed you use both let and var. If let is supported, use it instead of var. It will automagically solve your closure issues, because let creates variables with the block scope, instead of a function scope. Otherwise, you can try to replicate how let does it under the hood - throw the variable to the callback function. Something in the lines of:

    
        // ...
        for (var x = 0; x < Data.length; x++) {
            try { throw x }
            catch(iterator) {
                this.setState({
                    pageTitle: Data[iterator].title
                });
            }
        }
    

    PS. It is very difficult to follow your code, when it is so specific to your functionality. You could simplify it, and focus on the troubling issue. Most of the code you provided is not relevant to your problem, but makes us going through it anyway.