Handling null value inside Map - api

I'm learning to use BLOC pattern for consume API from newsapi.org. I have result JSON and Model like this from https://newsapi.org/v2/everythingq=flutter&apiKey=7f8eef4261bc4c29b26c4d5e93e8b5d6:
Json
{
"status": "ok",
"totalResults": 533,
"articles": [
{
"source": {
"id": "cnn",
"name": "CNN"
},
"author": "Sandee LaMotte, CNN",
"title": "Burnout linked to potentially deadly irregular heartbeat, study says",
"description": "If you're feeling bone-deep mental and physical exhaustion, or what is otherwise known as burnout, new research suggests you could be at a higher risk for a potentially fatal heart flutter.",
"url": "https://www.cnn.com/2020/01/13/health/burnout-linked-to-atrial-fibrillation-wellness/index.html",
"urlToImage": "https://cdn.cnn.com/cnnnext/dam/assets/200113120102-02-burnout-stock-super-tease.jpg",
"publishedAt": "2020-01-14T00:15:07Z",
"content": "(CNN)If you're feeling bone-deep mental and physical exhaustion, or what is otherwise known as burnout, new research suggests you could be at a higher risk for a potentially fatal heart flutter.\r\nAtrial fibrillation, also called AFib or AF, is the most common… [+4971 chars]"
},
{
"source": {
"id": "the-verge",
"name": "The Verge"
},
"author": "Ashley Carman",
"title": "The sex toy banned from CES last year is unlike anything we’ve ever seen",
"description": "Lora DiCarlo’s Osé personal massager made it to CES this year, after being banned and having its award revoked in 2019. The device is certainly innovative, using suction and movement to stimulate the G-spot and clitoris instead of vibration.",
"url": "https://www.theverge.com/2020/1/6/21051259/lora-dicarlo-sex-tech-toy-massager-awards-ban-ose-ces-2020",
"urlToImage": "https://cdn.vox-cdn.com/thumbor/G5zPZiQZgwqS9FqLqzUE3eyyLyA=/0x146:2040x1214/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset/file/19576504/loradicarlo1.jpg",
"publishedAt": "2020-01-06T14:25:23Z",
"content": "Its certainly innovative\r\nAshley Carman / The Verge\r\nLora DiCarlo likely didnt intend to change CES forever, but the sexual wellness company and its personal massager accomplished just that last year. After having an award revoked and being banned from the sh… [+3125 chars]"
},
{
"source": {
"id": null,
"name": "Codemagic.io"
},
"author": null,
"title": "Flutter vs. Other Mobile Development Frameworks: A UI and Performance Experiment",
"description": "In this experiment we created the same app five times, each time with a different framework. The frameworks I used were native Android, native iOS, Flutter, Xamarin Forms and React Native",
"url": "https://blog.codemagic.io/flutter-vs-ios-android-reactnative-xamarin/",
"urlToImage": "https://blog.codemagic.io/uploads/Codemagic-io_Blog_Flutter-Versus-Other-Mobile-Development-Frameworks_1.png",
"publishedAt": "2020-01-03T21:26:48Z",
"content": "Written by Bram De Coninck\r\nIve already read a lot of articles about how Flutter compares to other mobile development frameworks, but most of them were written from a theoretical point of view. Its already been well established that Flutter is a solid choice … [+24309 chars]"
},
{
"source": {
"id": null,
"name": "Insider.com"
},
"author": "dschild#businessinsider.com (Darcy Schild), Darcy Schild",
"title": "Kylie Jenner shared a sneak peek of her new makeup collection inspired by her daughter, Stormi",
"description": "Kylie Jenner/YouTube; Kylie Jenner/Instagram Kylie Jenner, the makeup mogul behind Kylie Cosmetics, is launching a collection of new eyeshadows, Lip Kits, lip glosses, and a blush inspired by her 1-year-old daughter, Stormi. Jenner gave her followers a sneak …",
"url": "https://www.insider.com/kylie-jenner-cosmetics-stormi-collection-when-to-buy-2020-1",
"urlToImage": "https://i.insider.com/5e24bb4b3ac0c9452948fd10?width=1200&format=jpeg",
"publishedAt": "2020-01-19T20:24:58Z",
"content": "Kylie Jenner is launching a makeup collection inspired by her 1-year-old daughter, Stormi Webster.\r\nThe Stormi Collection by Kylie Cosmetics will be available for purchase starting February 1, Jenner said in an Instagram Story post on Saturday.\r\nIn November 2… [+2710 chars]"
},
]
}
NewsModel
class NewsModel {
final Map<String, dynamic> source;
final String author;
final String title;
final String description;
final String url;
final String urlToImage;
final String publishedAt;
final String content;
NewsModel({
this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content,
});
NewsModel.fromJson(Map<String, dynamic> parsedJson)
: source = parsedJson['source']== null
? "Unknown Source"
: parsedJson['source'],
author = parsedJson['author'] == null
? "Unknown Author"
: parsedJson['author'],
title =
parsedJson['title'] == null ? "Unknown Title" : parsedJson['title'],
description = parsedJson['description'] == null
? "Unknown Description"
: parsedJson['description'],
url = parsedJson['url'] == null ? "Unknown Url" : parsedJson['url'],
urlToImage = parsedJson['urlToImage'] == null
? "https://homepages.cae.wisc.edu/~ece533/images/peppers.png"
: parsedJson['urlToImage'],
publishedAt = parsedJson['publishedAt'] == null
? "Unknown PublishedAt"
: parsedJson['publishedAt'],
content = parsedJson['content'] == null
? "Unknown Content"
: parsedJson['content'];
Map<String, dynamic> toMapForDb() {
return <String, dynamic>{
"source": source,
"author": author,
"title": title,
"description": description,
"url": url,
"urlToImage": urlToImage,
"publishedAt": publishedAt,
"content": content,
};
}
}
final newsModel = NewsModel();
source in this json is MAP,But one of its value is null (id). How to handling null value in my model ?
I'm trying handling this null value like this
source = parsedJson['source']['id'] == null? "Unknown Source" : parsedJson['source'],
But i get the error message Error From Bloc =type 'String' is not a subtype of type Map<String, dynamic>
My temporary solution to handling null value return Text(news.source["id"] ?? "null"); . But i want handling inside my model.
If you need BLOC source code
BLOC
import 'package:network/models/news_model.dart';
import 'package:repositories/repositories/news_repositories.dart';
import 'package:rxdart/subjects.dart';
class NewsBloc {
final _newsRepositories = NewsRepositories();
final _newsFetch = PublishSubject<List<NewsModel>>();
Stream<List<NewsModel>> get allEverythingNews => _newsFetch.stream;
Future<void> getEverythingNews() async {
try {
List<NewsModel> news = await _newsRepositories.getNewsEverything();
final newsAddSink = _newsFetch.sink.add(news);
return newsAddSink;
} catch (e) {
print("Error From Bloc =" + e.toString());
_newsFetch.sink.addError(e);
}
}
void dispose() {
_newsFetch.close();
}
}
final newsBloc = NewsBloc();

As can be seen from json you are getting object as a source and in your model you create a map to store source but when source is null then you are trying to assign String value to it. That’s why you are getting error.
Try To assign map like:
source = parsedJson['source']== null
? {"id": 0, "name": "Unknown Source"}
: parsedJson['source'],

By this error:
Error From Bloc =type 'String' is not a subtype of type Map
It is seems that the value provided in the NewsModel.fromJson() is a string and not a Map.
You need to do this:
NewsModel.fromJson(json.decode(STRING_FROM_API_RESPONSE))
Note that json is from import 'dart:convert';

Related

Handling multiple rows returned by IMPORTJSON script on GoogleSheets

I am trying to populate a google sheet using an API. But the API has more than one row to be returned for a single query. Following is the JSON returned by API.
# https://api.dictionaryapi.dev/api/v2/entries/en/ABANDON
[
{
"word": "abandon",
"phonetics": [
{
"text": "/əˈbændən/",
"audio": "https://lex-audio.useremarkable.com/mp3/abandon_us_1.mp3"
}
],
"meanings": [
{
"partOfSpeech": "transitive verb",
"definitions": [
{
"definition": "Cease to support or look after (someone); desert.",
"example": "her natural mother had abandoned her at an early age",
"synonyms": [
"desert",
"leave",
"leave high and dry",
"turn one's back on",
"cast aside",
"break with",
"break up with"
]
},
{
"definition": "Give up completely (a course of action, a practice, or a way of thinking)",
"example": "he had clearly abandoned all pretense of trying to succeed",
"synonyms": [
"renounce",
"relinquish",
"dispense with",
"forswear",
"disclaim",
"disown",
"disavow",
"discard",
"wash one's hands of"
]
},
{
"definition": "Allow oneself to indulge in (a desire or impulse)",
"example": "they abandoned themselves to despair",
"synonyms": [
"indulge in",
"give way to",
"give oneself up to",
"yield to",
"lose oneself in",
"lose oneself to"
]
}
]
},
{
"partOfSpeech": "noun",
"definitions": [
{
"definition": "Complete lack of inhibition or restraint.",
"example": "she sings and sways with total abandon",
"synonyms": [
"uninhibitedness",
"recklessness",
"lack of restraint",
"lack of inhibition",
"unruliness",
"wildness",
"impulsiveness",
"impetuosity",
"immoderation",
"wantonness"
]
}
]
}
]
}
]
By using the following calls via IMPORTJSON,
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/phonetics/text", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/partOfSpeech", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/definition", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/synonyms", "noHeaders")
=ImportJSON(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2), "/meanings/definitions/example", "noHeaders")
I am able to get the following in GoogleSheets,
Whereas, the actual output according to JSON should be,
As you can see a complete row is being overwritten. How can this be fixed?
EDIT
Following is the link to sheet for viewing only.
I believe your goal as follows.
You want to achieve the bottom image in your question on Google Spreadsheet.
Unfortunately, I couldn't find the method for directly retrieving the bottom image using ImportJson. So in this answer, I would like to propose a sample script for retrieving the values you expect using Google Apps Script. I thought that creating a sample script for directly achieving your goal might be simpler rather than modifying ImportJson.
Sample script:
function SAMPLE(url) {
var res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
if (res.getResponseCode() != 200) return res.getContentText();
var obj = JSON.parse(res.getContentText());
var values = obj[0].meanings.reduce((ar, {partOfSpeech, definitions}, i) => {
definitions.forEach(({definition, example, synonyms}, j) => {
var v = [definition, Array.isArray(synonyms) ? synonyms.join(",") : synonyms, example];
var phonetics = obj[0].phonetics[i];
ar.push(j == 0 ? [(phonetics ? phonetics.text : ""), partOfSpeech, ...v] : ["", "", ...v]);
});
return ar;
}, []);
return values;
}
When you use this script, please put =SAMPLE(CONCATENATE("https://api.dictionaryapi.dev/api/v2/entries/en/"&$A2)) to a cell as the custom formula.
Result:
When above script is used, the following
Note:
In this sample script, when the structure of the JSON object is changed, it might not be able to be used. So please be careful this.
References:
Class UrlFetchApp
Custom Functions in Google Sheets

How do I get info about a Youtube video's chapters from the API?

Recently, Youtube added the ability to break up their videos in the progress bar into sections called "chapters".
https://support.google.com/youtube/answer/9884579?hl=en
Currently I am able to get info about a video from the Youtube API. However, it doesn't seem like there's any info about a video's chapters, and I haven't found anything in the API documentation about chapters. Am I missing something, or is there simply no way to get chapter data yet?
As far as I know, such data is in plain text in the description of the video.
So, you can use the following example:
Video used in this demonstration: Top 10 Monsters with 2500 Attack in YuGiOh
URL Request:
https://www.googleapis.com/youtube/v3/videos?part=snippet&id=NNgYId7b4j0&key=[YOUR_API_KEY]
Response:
{
"kind": "youtube#videoListResponse",
"etag": "YpVLmrSx1iP8hAJOnumaTBoKqqQ",
"items": [
{
"kind": "youtube#video",
"etag": "oIoJq5F3RHvBbtVohafaJ_1SThU",
"id": "NNgYId7b4j0",
"snippet": {
"publishedAt": "2020-09-14T18:37:46Z",
"channelId": "UC0roOaAn95Rtgoe078RkVXQ",
"title": "Top 10 Monsters with 2500 Attack in YuGiOh",
"description": "In this video we'll go over the best monsters that have 2500 attack, and attack threshold for a lot of boss monsters actually.\n\nCheck out my DnD channel #TheD&DLogs \n\n--The List--\nIntro: (0:00)\n10- Blue-Eyes Spirit Dragon: (0:00)\n9- Invoked Mechaba: (2:14)\n8- Number S39: Utopia the Lightning: (3:23)\n7- Earthbound Immortal Aslla Piscu: (4:35)\n6- Eldlich the golden Lord: (6:04)\n5- True King Lithosagym the Disaster: (7:34)\n4- Block Dragon: (8:54)\n3- Astrograph sorcerer: (10:25)\n2- Beatrice lady of the eternal: (12:36)\n1- Firewall Dragon: (14:37)\n- \n-----------------------------------------\n#yugioh #top10 \n\nDuels are all done on EDOpro, its completely free and updated all the time. If you want it, just look for the EDOpro discord and you'll find all you need to download it from there\n\nSome of the Video backgrounds in this video were made by \"Amitai Angor AA VFX\" https://www.youtube.com/dvdangor2011\n\n\nhttps://twitter.com/hirumared\nhttps://twitter.com/TheDuelLogs",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/NNgYId7b4j0/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/NNgYId7b4j0/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/NNgYId7b4j0/hqdefault.jpg",
"width": 480,
"height": 360
},
"standard": {
"url": "https://i.ytimg.com/vi/NNgYId7b4j0/sddefault.jpg",
"width": 640,
"height": 480
},
"maxres": {
"url": "https://i.ytimg.com/vi/NNgYId7b4j0/maxresdefault.jpg",
"width": 1280,
"height": 720
}
},
"channelTitle": "TheDuelLogs",
"tags": [
"yugioh",
"ygo",
"dev",
"pro",
"link",
"duels",
"auto-matic duels",
"online",
"current",
"ban",
"list",
"dueling",
"network",
"theduellogs",
"the",
"duel",
"logs",
"loggs",
"Yu",
"Gi",
"Oh!",
"YGOpro",
"gimmick",
"links",
"top ten",
"2020",
"edopro"
],
"categoryId": "20",
"liveBroadcastContent": "none",
"localized": {
"title": "Top 10 Monsters with 2500 Attack in YuGiOh",
"description": "In this video we'll go over the best monsters that have 2500 attack, and attack threshold for a lot of boss monsters actually.\n\nCheck out my DnD channel #TheD&DLogs \n\n--The List--\nIntro: (0:00)\n10- Blue-Eyes Spirit Dragon: (0:00)\n9- Invoked Mechaba: (2:14)\n8- Number S39: Utopia the Lightning: (3:23)\n7- Earthbound Immortal Aslla Piscu: (4:35)\n6- Eldlich the golden Lord: (6:04)\n5- True King Lithosagym the Disaster: (7:34)\n4- Block Dragon: (8:54)\n3- Astrograph sorcerer: (10:25)\n2- Beatrice lady of the eternal: (12:36)\n1- Firewall Dragon: (14:37)\n- \n-----------------------------------------\n#yugioh #top10 \n\nDuels are all done on EDOpro, its completely free and updated all the time. If you want it, just look for the EDOpro discord and you'll find all you need to download it from there\n\nSome of the Video backgrounds in this video were made by \"Amitai Angor AA VFX\" https://www.youtube.com/dvdangor2011\n\n\nhttps://twitter.com/hirumared\nhttps://twitter.com/TheDuelLogs"
},
"defaultAudioLanguage": "en"
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}
}
Get the response:
response.items[0].snippet.description
Results:
"In this video we'll go over the best monsters that have 2500 attack, and attack threshold for a lot of boss monsters actually.
Check out my DnD channel #TheD&DLogs
--The List--
Intro: (0:00)
10- Blue-Eyes Spirit Dragon: (0:00)
9- Invoked Mechaba: (2:14)
8- Number S39: Utopia the Lightning: (3:23)
7- Earthbound Immortal Aslla Piscu: (4:35)
6- Eldlich the golden Lord: (6:04)
5- True King Lithosagym the Disaster: (7:34)
4- Block Dragon: (8:54)
3- Astrograph sorcerer: (10:25)
2- Beatrice lady of the eternal: (12:36)
1- Firewall Dragon: (14:37)
-
-----------------------------------------
#yugioh #top10
Duels are all done on EDOpro, its completely free and updated all the time. If you want it, just look for the EDOpro discord and you'll find all you need to download it from there
Some of the Video backgrounds in this video were made by "Amitai Angor AA VFX" https://www.youtube.com/dvdangor2011
https://twitter.com/hirumared
https://twitter.com/TheDuelLogs"
One more time YouTube Data API v3 doesn't provide a basic feature.
I would suggest you to use my open-source YouTube operational API, indeed by requesting https://yt.lemnoslife.com/videos?part=chapters&id=VIDEO_ID you would get a JSON with the video chapters (titles and timestamps) you are looking for in item['chapters']['chapters'].
Example of result with YouTube video id NNgYId7b4j0:
{
"kind": "youtube#videoListResponse",
"etag": "NotImplemented",
"items": [
{
"kind": "youtube#video",
"etag": "NotImplemented",
"id": "NNgYId7b4j0",
"chapters": {
"areAutoGenerated": false,
"chapters": [
{
"title": "10- Blue-Eyes Spirit Dragon",
"time": 0,
"thumbnails": [
{
"url": "https:\/\/i.ytimg.com\/vi\/NNgYId7b4j0\/hqdefault_4000.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLCoTrvu0Yu-iNxb7o4II-pxi5WVbQ",
"width": 168,
"height": 94
},
{
"url": "https:\/\/i.ytimg.com\/vi\/NNgYId7b4j0\/hqdefault_4000.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLCuupNwIgFIf9hXbjMsvpSGThFyhg",
"width": 336,
"height": 188
}
]
},
{
"title": "9- Invoked Mechaba",
"time": 134,
"thumbnails": [
{
"url": "https:\/\/i.ytimg.com\/vi\/NNgYId7b4j0\/hqdefault_135933.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLBe94BKNpQXvM2dUl75LtcgX0N03w",
"width": 168,
"height": 94
},
{
"url": "https:\/\/i.ytimg.com\/vi\/NNgYId7b4j0\/hqdefault_135933.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBULUhlI1OOjJiW6mpFDUhPzh4Adw",
"width": 336,
"height": 188
}
]
},
...
]
}
}
]
}
I am replying with this answer to help people such as myself who ended up on this video wanting to find a youtube chapter parser / extractor for text rather than where to find the chapter data. Just to add some further information, currently, there is no way to get the chapters from the official YouTube API, so the only way to get the chapters from a text-description response (like the YouTube API provides) is to parse it in some way:
My answer is in Javascript but it can easily be converted: The idea is to extract the MIN:SEC and HR:MIN:SEC timestamps then to generate the title we remove the word that includes them (So this would typically remove however people aesthetically wrap them too [00:00] or (00:00)
It's far from perfect, but in my experience it's better than the other solutions I've seen on github/npm at the time of writing this. You might want to also trim away starting and ending spaces and punctuational separators such as (-, :, ~, |) too
const parseChapters = (description) => {
// Extract timestamps (either 00:00:00, 0:00:00, 00:00 or 0:00)
const lines = description.split("\n")
const regex = /(\d{0,2}:?\d{1,2}:\d{2})/g
const chapters = []
for (const line of lines) {
// Match the regex and check if the line contains a matched regex
const matches = line.match(regex)
if (matches) {
const ts = matches[0]
const title = line
.split(" ")
.filter((l) => !l.includes(ts))
.join(" ")
chapters.push({
timestamp: ts,
title: title,
})
}
}
return chapters
}
Very late answer but it solved my problem.
You could use the code below. It's written in C# but it can easily be transcribed into another language. Since you can already get youtube video data, I assume you also have the description of the video.
private static IEnumerable<string> GetChaptersFromDescription(string text)
{
var lines = text.Split("\n");
var regex = new Regex(#"[0-9]:[0-9][0-9]");
foreach (var line in lines)
{
if (regex.IsMatch(line))
{
yield return line;
}
}
}

How to validate Nested JSON Response

I am facing issue while validate Nested JSON response in API Testing using Karate Framework.
JSON Response:
Feed[
{ "item_type": "Cake" ,
"title": "Birthday Cake",
"Services":
[
{
"id": "1",
"name": {
"first_name": "Rahul",
"last_name": "Goyal"
}
},
{
"id": "2",
"name":{
"first_name": "Hitendra",
"last_name": "garg"
}
}
]
},
{
"item_type":"Cycle",
"title": "used by"
},
{
"item_type": "College"
"dept":
[
{"branch": "EC"},
{"branch": "CSE"},
{"branch": "CIVIL"}
]
},
]
}
Now i need to validate response based on Item type. as we can see nested JSON is different for different item_type.
I have tried with below solution
Schema Design for Item_type value cake
def Feed_Cake_Service_name={first_name: '#string',last_name: '#string'}
def Feed_Cake_Services= {id: '#string',name:#(Feed_Cake_Service_name)}
def Feed_Cake={item_type:'#string',title: '#string',Services: '#[] Feed_Cake_Services'}
def Feed_Cake_Response= {Feed: '#[] Feed_Cake'}
Schema Design for item_type Cycle
def Feed_Cycle={item_type:'#string',title:'#string'}
Schema Design for item type College
def Feed_College_Dept_Branch={branch:'#string'}
def Feed_College={item_type:'#string',dept: '[] Feed_College_Dept_Branch'}
now if i want to verify only item type Cake then i have written match like below
match response contains Feed_Cake_Response
but here my test case is getting failed. because it is comparing for all item type.
so here i have two question
1.) How we can compare particular item type schema
2.) How we can include all item type in one match equation since any item type can come in JSON response , and i want to validate all
Thanks
I'll just give you one hint. For the rest, read the documentation please:
* def item = { item_type: '#string', title: '##string', dept: '##[]', Services: '##[]' }
* match each response == item

Figure out different values to send partial update to server

From a form submission I receive two objects: the original values and the dirty values. I like to figure out how to create a diff to send to the server using the following rules:
id field of the root object should always be included
all changed primitive values should be included
all nested changes should be included as well.
if a nested value other than id changed, it should include id as well.
Original values:
{
"id":10,
"name": "tkvw"
"locale": "nl",
"address":{
"id":2,
"street": "Somewhere",
"zipcode": "8965",
},
"subscriptions":[8,9,10],
"category":{
"id":6
},
}
Example expected diff objects:
1) User changes field name to "Foo"
{
"id":10,
"name":"foo"
}
2) User changes field street on address node and category
{
"id":10,
"address":{
"id": 2,
"street":"Changed"
},
"category":{
"id":5
}
}
I do understand the basics of functional programming, but I just need a hint in the right direction (some meta code maybe).
Take a look at JSON Patch (rfc6902), JSON Patch is a format for describing changes to a JSON document. For example:
[
{ "op": "replace", "path": "/baz", "value": "boo" },
{ "op": "add", "path": "/hello", "value": ["world"] },
{ "op": "remove", "path": "/foo"}
]
You generate a patch by comparing to JS objects/arrays, and then you can apply the patch to the original object (on the server side for example) to reflect changes.
You can create a patch using the fast-json-patch lib.
const obj1 = {"id":10,"name":"tkvw","locale":"nl","address":{"id":2,"street":"Somewhere","zipcode":"8965"},"subscriptions":[8,9,10],"category":{"id":6}};
const obj2 = {"id":10,"name":"cats","locale":"nl","address":{"id":2,"street":"Somewhere","zipcode":"8965"},"subscriptions":[8,9,10,11],"category":{"id":7}};
const delta = jsonpatch.compare(obj1, obj2);
console.log('delta:\n', delta);
const doc = jsonpatch.applyPatch(obj1, delta).newDocument;
console.log('patched obj1:\n', doc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-json-patch/2.0.6/fast-json-patch.min.js"></script>

JSON parsing using JSON.net

I am accessing the facebook api and using the json.net library (newtonsoft.json.net)
I declare a Jobject to parse the content and look for the specific elements and get their values. Everything works fine for the first few but then I get this unexplained nullexception error " (Object reference not set to an instance of an object)
Now I took a look at the declaration but cannot see how to change it. Any help appreciated:
Dim jobj as JObject = JObject.Parse(responseData)
message = jobj("message").tostring
The error occurs at the last line above.I check to see if message is null and then look for the next desired field as follows
catch exception..
dim jobj2 as JObject = JObject.parse(responseData)
description = jobj2("description").tostring
JSON responsedata:
{
"id": "5281959998_126883980715630",
"from": {
"name": "The New York Times",
"category": "Company",
"id": "5281959998"
},
"picture": "http://external.ak.fbcdn.net /safe_image.php?d=e207958ca7563bff0cdccf9631dfe488&w=
90&h=90&url=http\u00253A\u00252F\u00252Fgraphics8.nytimes.com\u00252Fimages\u00252F2011\u00252F02\u00252F04\u00252Fbusiness\u00252FMadoff\u00252FMadoff-thumbStandard.jpg",
"link": "http://nyti.ms/hirbn0",
"name": "JPMorgan Said to Have Doubted Madoff Long Before His Scheme Was Revealed",
"caption": "nyti.ms",
"description": "Newly unsealed court documents show that bank
executives were suspicious of Bernard Madoff\u2019s accounts
and steered clients away from him but did not alert regulators.",
"icon": "http://static.ak.fbcdn.net/rsrc.php/yD/r/aS8ecmYRys0.gif",
"type": "link",
"created_time": "2011-02-04T16:09:03+0000",
"updated_time": "2011-02-06T20:09:51+0000",
"likes": {
"data": [
{
"name": "Siege Ind.",
"category": "Product/service",
"id": "152646224787462"
},
{
"name": "Lindsey Souter",
"id": "100000466998283"
},
This is one example where "message" does not appear in the first few lines but appears later. So what I do is look for position of message and description and which ever is first go and get that and if I get an error or the fields do not return anything, I try and parse by regex and even that is not working right.
Well, presumably jobj("message") has returned Nothing, which will happen if jobj doesn't have a message property. If you think this is incorrect, please post a short but complete piece of JSON to help us investigate.
(Is there any reason why you're declaring message and assigning it a value on the second line, only to overwrite that value on the third line?)