metalsmith-prismic icon indicating copy to clipboard operation
metalsmith-prismic copied to clipboard

Error when querying documents with 'slice zones'

Open danhalliday opened this issue 7 years ago • 4 comments

I get the following error when querying for documents whose data model has the 'slice zone' turned on. Not sure where to start with this!

Template:

---
prismic:
  documents:
    query: '[[at(document.type, "page")]]'
    allPages: true
---

<%= prismic.documents.results[0].data.title.json.value %>

Error:

Metalsmith                                        
  starting development - ^C to exit                 
                                                
     ···    first build                             
     ···    livereload                              
     ···    http://localhost:3000                   
                                                
            Starting up...                          
/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:3009
        if (classForType[field.type]) {
                              ^

TypeError: Cannot read property 'type' of undefined
    at initField (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:3009:31)
    at SliceZone (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:2917:28)
    at initField (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:3010:20)
    at Object.parseFragments (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:3050:35)
    at Document (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:1844:51)
    at parseDoc (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:314:20)
    at Array.map (<anonymous>)
    at Object.callback (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:462:53)
    at /my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:1296:18
    at IncomingMessage.<anonymous> (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/dist/prismic.io.js:1264:27)
    at emitNone (events.js:110:20)
    at IncomingMessage.emit (events.js:207:7)
    at endReadableNT (_stream_readable.js:1059:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

danhalliday avatar Nov 06 '17 16:11 danhalliday

Same issue.

The problem originates in initField(field) while checking for a helper class for the field type. This is within the Prismic JS SDK (not the metalsmith-prismic repo).

When the Fragments:SliceZone helper looks for the fragment type... there is no helper class for {type: "Slice"} in the library. (This function seems to be used for both parent fields and child components).

Looks like the data was structured differently in the past. Slice fragments are broken into non-repeat and repeat object properties, and the code is just looking for a stack of slices.

This will require refactoring on both: SliceZone and Slice objects to accommodate iterating and parsing fragments.

doublejosh avatar Nov 20 '17 21:11 doublejosh

I can confirm that site builds (without slices) still work after updating to the prismic js-sdk to 3.6.1 from 1.4.0 ...this is promising for being able to use slices within what seems like a new Prismic structure.

doublejosh avatar Feb 19 '18 02:02 doublejosh

After updating to Prismic JS SDK 3.6.1 a new error pops up with slices...

/my/project/path/node_modules/metalsmith-prismic/lib/index.js:244
          if (!fragment.asHtml) {
                       ^

TypeError: Cannot read property 'asHtml' of undefined
    at processSingleFragment (/my/project/path/node_modules/metalsmith-prismic/lib/index.js:244:24)
    at /my/project/path/node_modules/metalsmith-prismic/lib/index.js:328:22
    at Function._.map._.collect (/my/project/path/node_modules/metalsmith-prismic/node_modules/underscore/underscore.js:172:24)
    at processSingleFragment (/my/project/path/node_modules/metalsmith-prismic/lib/index.js:327:46)
    at /my/project/path/node_modules/metalsmith-prismic/lib/index.js:216:20
    at Function._.map._.collect (/my/project/path/node_modules/metalsmith-prismic/node_modules/underscore/underscore.js:172:24)
    at processRetrievedDocument (/my/project/path/node_modules/metalsmith-prismic/lib/index.js:211:32)
    at /my/project/path/node_modules/metalsmith-prismic/lib/index.js:198:20
    at Function._.map._.collect (/my/project/path/node_modules/metalsmith-prismic/node_modules/underscore/underscore.js:172:24)
    at processRetrievedContent (/my/project/path/node_modules/metalsmith-prismic/lib/index.js:197:32)
    at prismicQueryCallback (/my/project/path/node_modules/metalsmith-prismic/lib/index.js:157:29)
    at /my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/lib/api.js:507:23
    at /my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/lib/api.js:497:15
    at ApiCache.set (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/lib/cache.js:30:12)
    at Object.callback (/my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/lib/api.js:496:19)
    at /my/project/path/node_modules/metalsmith-prismic/node_modules/prismic.io/lib/requests.js:225:10

I thought a manual approach could save the day, but sadly the htmlSerializer function won't work in the config object because it's not included in the metalsmith-prismic-server implementation here...

https://github.com/futurice/metalsmith-prismic-server/blob/master/src/metalsmith.js

doublejosh avatar Feb 19 '18 08:02 doublejosh

Here is the problem code (was marked with a //TODO)...

/my/project/path/node_modules/metalsmith-prismic/lib/index.js

} else if (fragment instanceof Prismic.Fragments.SliceZone) {
  // TODO
  childPromises.push(Promise.all(_.map(fragment.value, function(sliceFragment) {
    return processSingleFragment(sliceFragment.value, ctx, queryMetadata).then(function (subFragmentObject) {
      subFragmentObject.sliceType = sliceFragment.sliceType;
      subFragmentObject.sliceLabel = sliceFragment.label;
      return subFragmentObject;
    });
  })).then(function(children) {
    return fragmentObject.children = children;
  }));
}

doublejosh avatar Feb 19 '18 09:02 doublejosh