guncebektas / meteor-friendly-slugs

Meteor package to generate URL friendly slugs from a field with auto-incrementation to ensure unique URLs.
65 stars 15 forks source link

gets different slugs on client and server #29

Closed samudranb closed 8 years ago

samudranb commented 8 years ago

I am trying to insert a "question" document into the DB, and then redirect to a page to display the newly inserted question. The doc does get inserted, but the redirect happens to the pre-existing question instead. The problem seems to be that the highest index is not available on the client side. Is this because "friendlySlugs" is not being published to the client side?

On the server, I get:

I20160320-21:58:52.951(-7)? friendlySlugs DEBUG: Modifier= false
I20160320-21:58:52.951(-7)? friendlySlugs DEBUG: Create= false
I20160320-21:58:52.952(-7)? friendlySlugs DEBUG: Slugging From= q2
I20160320-21:58:52.954(-7)? friendlySlugs DEBUG: SlugBase before reduction= q2
I20160320-21:58:52.954(-7)? friendlySlugs DEBUG: SlugBase after reduction= q2
I20160320-21:58:52.954(-7)? friendlySlugs DEBUG: Highest indexed base found↓
I20160320-21:58:52.955(-7)? { _id: 'NvYtRHBuXQ7FYvTLP',
I20160320-21:58:52.955(-7)?   friendlySlugs: { slug: { index: 1 } } }
I20160320-21:58:52.962(-7)? friendlySlugs DEBUG: finalSlug= q2-2
I20160320-21:58:52.962(-7)? friendlySlugs DEBUG: = Set to update
I20160320-21:58:52.962(-7)? friendlySlugs DEBUG: Final Doc↓
I20160320-21:58:52.963(-7)? { questionText: 'q2',
I20160320-21:58:52.963(-7)?   createdAt: Sun Mar 20 2016 21:58:52 GMT-0700 (PDT),
I20160320-21:58:52.963(-7)?   ownerId: 'Ep7o4agRd9jZRyYmZ',
I20160320-21:58:52.963(-7)?   askedBy: [ 'Ep7o4agRd9jZRyYmZ' ],
I20160320-21:58:52.963(-7)?   answers: [],
I20160320-21:58:52.964(-7)?   _id: 'h3i3pQvYqguF4Z5Et',
I20160320-21:58:52.964(-7)?   friendlySlugs: { slug: { base: 'q2', index: 2 } },
I20160320-21:58:52.964(-7)?   slug: 'q2-2' }
I20160320-21:58:52.965(-7)? New Question ID:  h3i3pQvYqguF4Z5Et
I20160320-21:58:53.084(-7)? Going to: /question/q2-2

And on the client, I get:

friendlySlugs DEBUG: = before.insert function
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: = Begin runSlug
todda00_friendly-slugs.js:322 friendlySlugs DEBUG: Options↓
todda00_friendly-slugs.js:323 ObjectcreateOnUpdate: truedebug: truedistinct: truedistinctUpTo: Array[0]maxLength: 0slugField: "slug"slugFrom: "questionText"transliteration: Array[31]updateSlug: true__proto__: Object
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: Modifier= false
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: Create= false
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: Slugging From= q2
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: SlugBase before reduction= q2
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: SlugBase after reduction= q2
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: Highest indexed base found= undefined
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: finalSlug= q2
todda00_friendly-slugs.js:325 friendlySlugs DEBUG: = Set to update
todda00_friendly-slugs.js:322 friendlySlugs DEBUG: Final Doc↓
todda00_friendly-slugs.js:323 Object
methods.js:26 New Question ID:  h3i3pQvYqguF4Z5Et
methods.js:29 Going to: /question/q2

Observations:

  1. Those last 2 lines in both the logs are created by the same console.log statements in my methods.js. As you can see, it does insert the document, but sends it to the wrong URL.
  2. Highest indexed base found for server is the right object, but the same for the client is undefined. I believe this is the root of the problem.

My code in methods.js:

    new_q_id = Questions.insert(data);
    console.log("New Question ID: ", new_q_id);
    new_slug = Questions.findOne(new_q_id).slug;

    console.log("Going to: /question/" + new_slug);

    FlowRouter.go('/question/' + new_slug);

In collections.js:

Schemas.Questions = new SimpleSchema({
...
  },
  friendlySlugs: {
    type: Object,
    optional: true,
    blackbox: true,
  },
  slug: {
    type: String,
    optional: true
  },
...
);

Questions.friendlySlugs({
  slugFrom: 'questionText',
  slugField: 'slug',
  distinct: true,
  updateSlug: true,
  debug: true,
  createOnUpdate: true,
});
todda00 commented 8 years ago

This is happening because the client side is not subscribed to all the data, so it thinks q2 is the correct slug. The best way to handle this situation is to do one of the following:

  1. Complete your insert and slug lookup commands in a server only method, which has access to all data and will use the correct slug.
  2. create a server method to receive an _id and return the slug, then call this on the client before routing.