Sunday, 1 September 2019

How to check if comment belongs to current user

So I am trying to create a function where users can delete their own comment/report others.

I've done this with post so I assumed I would use the same method..which is grab the owner of the comment's uid and check if that is the current user or not. If it is the current user then I will set up the alert controller to display "delete" else it'll be "report"

Here is a sample code of the post function that works correctly


  func handleOptionsTapped(for cell: FollowingCell) {

 guard let post = cell.post else { return }

        // If post belongs to current user display delete action sheet.. else report

if post.ownerUid == Auth.auth().currentUser?.uid {
            let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

            alertController.addAction(UIAlertAction(title: "Delete Post", style: .destructive, handler: { (_) in
                post.deletePost()


Also the post value in FollowingCell

 var post: Post? {
        didSet {
            guard let ownerUid = post?.ownerUid else { return }
            guard let imageUrl = post?.imageUrl else { return }


            Database.fetchUserWithUID(with: ownerUid) { (user) in
                self.profileImage.loadImage(with: user.profileImageUrl)
                self.username.setTitle(user.username, for: .normal)
                self.configurePostCaption(user: user)
            }
            postImage.loadImage(with: imageUrl)
            configureLikeButton()



            }
}



Here is the code I have for comments


   @objc func handleCommentTapped(for cell: CommentCell) {


         guard let comment = cell.comment else { return }

        // If comment belongs to current user

        if comment.uid == Auth.auth().currentUser?.uid {
            print("this is my comment")

        } else {
            print("this is another users comment")
        }

    }

Also here is the code I have for the CommentCell

 var comment: Comment? {

            didSet {
                guard let comment = self.comment else { return }
                guard let uid = comment.uid else { return }
                guard let user = self.comment?.user else { return }
                guard let profileImageUrl = user.profileImageUrl else { return }

                Database.fetchUserWithUID(with: uid) { (user) in

                    self.profileImageView.loadImage(with: profileImageUrl)

                    self.configureCommentLabel()

                }
            }
    }


When I run the program I get a crash

Thread 1: EXC_BAD_ACCESS (code=257, address=0x1a2494098a1)

on the line guard let comment = cell.comment else { return }

I ran a break point and everything is coming out to nil ( the text of the comment, the users information who posted the comment, everything) Does anyone know how I can fix this? I am also using Active Label so I'm not sure if that is playing a factor not. Thanks!



from How to check if comment belongs to current user

Can I modify Vue.js VNodes?

I want to assign some attributes and classes to the children VNode through data object? Everything works perfectly. But during my Vue.js investigation, I have not seen such pattern in use, that's why I don't think it's good idea to modify children VNode's.

But that approach sometimes comes in handy – for example I want to assign to all the buttons in default slot the aria-label attribute.

See example below, using default stateful components:

Vue.component('child', {
  template: '<div>My role is </div>',
})

Vue.component('parent', {
  render(h) {
    const {
      default: defaultSlot
    } = this.$slots

    if (defaultSlot.length) {
      defaultSlot.forEach((child, index) => {
        if (!child.data) child.data = {}
        if (!child.data.attrs) child.data.attrs = {}

        const {
          data
        } = child

        data.attrs.role = 'button'
        data.class = 'bar'
        data.style = `color: #` + index + index + index
      })
    }

    return h(
      'div', {
        class: 'parent',
      },
      defaultSlot,
    )
  },
})

new Vue({
  el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <parent>
    <child></child>
    <child></child>
    <child></child>
    <child></child>
    <child></child>
  </parent>
</div>

And here is examples using stateless functional components:

Vue.component('child', {
  functional: true,
  render(h, {
    children
  }) {
    return h('div', {
      class: 'bar'
    }, children)
  },
})

Vue.component('parent', {
  functional: true,
  render(h, {
    children,
    scopedSlots
  }) {
    const defaultScopedSlot = scopedSlots.default({
      foo: 'bar'
    })

    if (defaultScopedSlot.length) {
      defaultScopedSlot.forEach((child, index) => {
        child.data = {
          style: `color: #` + index + index + index
        }
        
        child.data.attrs = {
          role: 'wahtever'
        }
      })
    }
    return h(
      'div', {
        class: 'parent',
      },
      defaultScopedSlot,
    )
  },
})

new Vue({
  el: '#app',
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <parent>
    <template v-slot:default="{ foo }">
    <child></child>
    <child></child>
    <child></child>
  </template>
  </parent>
</div>

I am waiting for the following answers:

  1. Yes, you can use it, there are no potential problems with this approach.

  2. Yes, but these problem(s) can happen.

  3. No, there are a lot of problem(s).

UPDATE:

That another good approach I have found it's to wrap child VNode into the another created VNode with appropriate data object, like this:

const wrappedChildren = children.map(child => {
  return h("div", { class: "foo" }, [child]);
});

Using this approach I have no fear modifying children VNode's.

Thank you in advance.



from Can I modify Vue.js VNodes?

Populate month wise dataframe from two date columns

I have a PySpark dataframe like this,

+----------+--------+----------+----------+
|id_       | p      |d1        |  d2      |
+----------+--------+----------+----------+
|  1       | A      |2018-09-26|2018-10-26|
|  2       | B      |2018-06-21|2018-07-19|
|  2       | B      |2018-08-13|2018-10-07|
|  2       | B      |2018-12-31|2019-02-27|
|  2       | B      |2019-05-28|2019-06-25|
|  3       |C       |2018-06-15|2018-07-13|
|  3       |C       |2018-08-15|2018-10-09|
|  3       |C       |2018-12-03|2019-03-12|
|  3       |C       |2019-05-10|2019-06-07|
| 4        | A      |2019-01-30|2019-03-01|
| 4        | B      |2019-05-30|2019-07-25|
| 5        |C       |2018-09-19|2018-10-17|
-------------------------------------------

From this dataframe I have to derive another dataframe which have n columns. Where each column is a month from month(min(d1)) to month(max(d2)).

I want a in the derived dataframe for a row in the actual dataframe and the column values must be number of days in that month.

For example,

for first row, where id_ is 1 and p is A, I want to get a row in the derived dataframe where column of 201809 with value 5 and column 201810 with value 26.

For second row where id_ is 2 and p is B, I want to get a row in the derived dataframe where column of 201806 should be 9 and 201807 should be 19.

For the second last row, I want the columns 201905 filled with value 1, column 201906 with value 30, 201907 with 25.

So basically, I want the dataframe to be populated such a way that, for each row in my original dataframe I have a row in the derived dataframe where the columns in the table that corresponds to the month should be filled, for the range min(d1) to max(d2) with value number of days that is covered in that particular month.

I am currently doing this in the hard way. I am making n columns, where columns range for dates from min(d1) to max(d2). I am filling theses column with 1 and then melting the data and filtering based on value. Finally aggregating this dataframe to get my desired result, then selected the max valued p.

In codes,

d = df.select(F.min('d1').alias('d1'), F.max('d2').alias('d2')).first()

cols = [ c.strftime('%Y-%m-%d') for c in pd.period_range(d.d1, d.d2, freq='D') ]

result = df.select('id_', 'p', *[ F.when((df.d1 <= c)&(df.d2 >= c), 1).otherwise(0).alias(c) for c in cols ])

melted_data = melt(result, id_vars=['id_','p'], value_vars=cols)

melted_data = melted_data.withColumn('Month', F.substring(F.regexp_replace('variable', '-', ''), 1, 6))

melted_data = melted_data.groupBy('id_', 'Month', 'p').agg(F.sum('value').alias('days'))

melted_data = melted_data.orderBy('id_', 'Month', 'days', ascending=[False, False, False])

final_data = melted_data.groupBy('id_', 'Month').agg(F.first('p').alias('p'))

This codes takes a lot of time to run in decent configurations. How can I improve this.?

How can I achieve this task in a more optimized manner.? Making every single date in the range dont seems to be the best solution.

A small sample of the needed output is shown below,

+---+---+----------+----------+----------+----------+-------+
|id_|p  |201806    |201807    |201808    | 201809   | 201810|
+---+---+----------+----------+----------+----------+-------+
| 1 | A |         0|        0 |         0|      4   | 26    |
| 2 | B |         9|        19|         0|      0   | 0     |
| 2 | B |         0|        0 |        18|      30  | 7     |
+---+---+----------+----------+----------+----------+-------+



from Populate month wise dataframe from two date columns