1

I have two FB page feeds and I am trying to join them together in one object (or list, or array) that I can read, sorted on "created_time" data. I have changed question code after comments.

Here's my JSON data:

{
   "data": [
      {
         "message": "Zimovanje u punom tijeku :-)",
         "created_time": "2017-01-04T10:06:57+0000",
         "type": "photo",
         "name": "Photos from Odred izvi\u0111a\u010da Javor's post",
         "id": "217384491624554_1572127976150192"
      },
      {
         "message": "Skup\u0161tina Odreda izvi\u0111a\u010da tijeku...",
         "created_time": "2016-12-22T19:52:12+0000",
         "type": "photo",
         "name": "Timeline Photos",
         "id": "217384491624554_1552374844792172"
      },
    ...

And here is my code until now:

Public Class FBData
    Public Property data As New List(Of FBFeed)
End Class

Public Class FBFeed
    Public Property message As String
    Public Property created_time As DateTime
    Public Property id As String
    Public Property type As String
    Public Property name As String
End Class

Public Shared Function GetPosts( PageId As String, accessToken As String ) As FBData

    Dim APIlink As String = "https://graph.facebook.com/" & pageID & "/posts?fields=full_picture,message,created_time,id,link,type,name,description&access_token=" & accessToken

    Dim client As New WebClient()
    client.Encoding = System.Text.Encoding.UTF8
    Dim strJson As [String] = client.DownloadString(APIlink)

    Dim result As FBData = Newtonsoft.Json.JsonConvert.DeserializeObject(Of FBData)( strJson )

    Return result

End Function

In main code I am calling this function:

Dim array1 As FBData = GetPosts ( "OI.Plavipingvin", accessToken )
Dim array2 As FBData = GetPosts ( "217384491624554", accessToken )

'Merging two lists
array1.data.AddRange(array2.data.ToArray)

'Order final list
Dim OrderedPosts as List(Of FBFeed) = array1.data.OrderByDescending(Function(x) x.created_time) 

For Each Msg As FBFeed In array1.data
    Response.Write( Msg.created_time & "<br />" )
    Response.Write( "<image width=""100px"" height=""100px"" src=""" & Msg.full_picture & """><br />" )
Next

The line Dim OrderedPosts as List produces error System.InvalidCastException: Unable to cast object of type 'System.Linq.OrderedEnumerable 2[_feed+FBFeed,System.DateTime]' to type 'System.Collections.Generic.List 1[_feed+FBFeed]'..

1
  • tools already exist that make this easier for you to do. desrialize the json to a collection of your class. use linq union extension to join the collections and the result you can do with what ever you wish. even sort on create_time Commented Jan 5, 2017 at 13:49

3 Answers 3

1

I had to clean up and sanitize your sample data, but came up with this. Once you have the initial object MyData subsequent JSON messages can be added to the List data. Hopefully, this gives you the clue you needed:

Module Module1

    Sub Main()
        Dim JsonSample1 As String = "{'data': [
      {
         'message': 'Zimovanje u punom tijeku :-)',
         'created_time': '2017-01-04T10:06:57+0000',
         'type': 'photo',
         'name': 'Photos from Odred izvi\u0111a\u010da Javor\'s post',
         'id': '217384491624554_1572127976150192'
      }]}"

        Dim JsonSample2 As String = "{'data': [
      {
         'message': 'Skup\u0161tina Odreda izvi\u0111a\u010da tijeku...',
         'created_time': '2016-12-22T19:52:12+0000',
         'type': 'photo',
         'name': 'Timeline Photos',
         'id': '217384491624554_1552374844792172'
      }]}"


        Dim MyData As FBData = Newtonsoft.Json.JsonConvert.DeserializeObject(Of FBData)(JsonSample1)
        Dim MyData1 As FBData = Newtonsoft.Json.JsonConvert.DeserializeObject(Of FBData)(JsonSample2)

        MyData.data.AddRange(MyData1.data.ToArray)

        Debug.Print("Msg Count: {0}", MyData.data.Count.ToString)
        For Each Msg As FBFeed In MyData.data
            Debug.Print("{0}{1}{2}", Msg.created_time, vbTab, Msg.message)
        Next

        Debug.Print("")

        For Each Msg As FBFeed In MyData.data.OrderBy(Function(x) x.created_time)
            Debug.Print("{0}{1}{2}", Msg.created_time, vbTab, Msg.message)
        Next

        Debug.Print("")

        For Each Msg As FBFeed In MyData.data.OrderByDescending(Function(x) x.created_time)
            Debug.Print("{0}{1}{2}", Msg.created_time, vbTab, Msg.message)
        Next
    End Sub

    Public Class FBData
        Public Property data As New List(Of FBFeed)
    End Class

    Public Class FBFeed
        Public Property message As String
        Public Property created_time As DateTime
        Public Property id As String
        Public Property type As String
        Public Property name As String
    End Class

End Module

The output looks like this:

Msg Count: 2
01/04/2017 05:06:57 Zimovanje u punom tijeku :-)
12/22/2016 14:52:12 Skupština Odreda izviđača tijeku...

12/22/2016 14:52:12 Skupština Odreda izviđača tijeku...
01/04/2017 05:06:57 Zimovanje u punom tijeku :-)

01/04/2017 05:06:57 Zimovanje u punom tijeku :-)
12/22/2016 14:52:12 Skupština Odreda izviđača tijeku...
Sign up to request clarification or add additional context in comments.

13 Comments

Thank you for quick answer, but I think that is not what I need. Problem is that I really don't know how to sort that List(Of FBFeed). If I have two lists, I can compare them and add corresponding item to New List. Can I just create Dim MyData3 As FBData, and then do "MyData3.add( MyData3(3) )" { or is it "MyData.data(3)" ? }
Are MyData and MyData1 lists? Can I just create Dim MyData3 As FBData, and then do "MyData3.add( MyData3(3) )" { or is it "MyData.data(3)" ? } to add 3rd item in list to the MyData3 list?
MyData and MyData1 are instances of the FBData class, which contains the data object that is a List(of FBFeed). By combining the messages in one list, Linq has Orderby for sorting. See this question
Can you please show me how to combine that here, because I really don't understand that. Thanks again.
That's what MyData.data.AddRange(MyData1.data.ToArray) does...it adds the second JSON to the first. Change your GetPosts function to return an instance of FBData and add the .data.ToArray to your original growing message list (MyData)
|
1

Given the OP's updated code, here's an alternate solution using SortedDictionary. Note that there will be some dropped messages that have the same created_time to the millisecond. Mostly these would likely be msgs received previously, but there could be a tiny bit of coincidental loss.

Imports Newtonsoft.Json
Imports System.Timers
Imports System.Net

Module Module2

    Friend WithEvents Timer1 As New Timers.Timer(5000)

    Private OrderedPosts As New SortedDictionary(Of DateTime, FBFeed)
    Private AccessToken As String = "Your Token Goes Here"

    Sub Main()
        Timer1.Enabled = True
        Console.ReadKey()
    End Sub

    Private Sub Timer1_Elapsed(sender As Object, e As ElapsedEventArgs) Handles Timer1.Elapsed
        GetPosts("OI.Plavipingvin", AccessToken)
        GetPosts("217384491624554", AccessToken)

        Debug.Print("Msg Count: {0}", OrderedPosts.Count.ToString)
        For Each Post As FBFeed In OrderedPosts.Values
            Debug.Print("{0}{1}{2}", Post.created_time, vbTab, Post.message)
        Next
        Debug.Print("")
    End Sub

    Private Sub GetPosts(PageId As String, accessToken As String)
        Dim APIlink As String = String.Format("https://graph.facebook.com/{0}/posts?fields=full_picture,message,created_time,id,link,type,name,description&access_token={1}", PageId, accessToken)

        Using WebClient As New WebClient()
            WebClient.Encoding = Text.Encoding.UTF8

            With JsonConvert.DeserializeObject(Of FBData)(WebClient.DownloadString(APIlink))
                For Each Post As FBFeed In .data
                    Try
                        OrderedPosts.Add(Post.created_time, Post)
                    Catch ex As Exception
                        Debug.Print("Duplicate post created_time: {0}", Post.created_time.ToString("O"))
                    End Try
                Next
            End With
        End Using
    End Sub

    Private Class FBData
        Public Property data As New List(Of FBFeed)
    End Class

    Private Class FBFeed
        Public Property message As String
        Public Property created_time As DateTime
        Public Property id As String
        Public Property type As String
        Public Property name As String
    End Class

End Module

2 Comments

I haven't tried this code, but +1 for so much help.
I have another problem, please if you can help me with this (I have 20 page IDs to call, and then show sorted JSON - this would be more effective way to call them in one API call and then sort one JSON array) - link
0

So, thanks to @MrGadget help I come to solution to my problem, just because I couldn't find whole solution anywhere on the net.

Dim accessToken As String= appID & "|" & appSecret

Dim array1 As FBData = GetPosts ( "OI.Plavipingvin", accessToken )
Dim array2 As FBData = GetPosts ( "217384491624554", accessToken )

'Merging two lists
array1.data.AddRange(array2.data.ToArray)

'Order final list
'Dim OrderedPosts as List(Of FBFeed) = array1.data.OrderByDescending(Function(x) x.created_time)

For Each Msg As FBFeed In array1.data.OrderByDescending(Function(x) x.created_time)
    Response.Write( Msg.created_time & "<br />" )
    Response.Write( "<image width=""100px"" height=""100px"" src=""" & Msg.full_picture & """><br />" )
Next

And here are FBData Class and function to get and serialise JSON.

Public Class FBData
    Public Property data As New List(Of FBFeed)
End Class

Public Class FBFeed
    Public Property full_picture As String
    Public Property message As String
    Public Property created_time As DateTime
    Public Property id As String
    Public Property link As String
    Public Property type As String
    Public Property name As String
    Public Property description As String
End Class

Public Shared Function GetPosts( PageId As String, accessToken As String ) As FBData

    Dim APIlink As String = "https://graph.facebook.com/" & pageID & "/posts?fields=full_picture,message,created_time,id,link,type,name,description&access_token=" & accessToken

    Dim client As New WebClient()
    client.Encoding = System.Text.Encoding.UTF8
    Dim strJson As [String] = client.DownloadString(APIlink)

    Dim result As FBData = Newtonsoft.Json.JsonConvert.DeserializeObject(Of FBData)( strJson )

    Return result

End Function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.